Is beginBackgroundTask() expected to dispatch to main?

The name of the function beginBackgroundTask appears to imply that it is safe to call from a background thread.

However, because this is part of the UIApplication class, it causes a dispatch to the main thread first. This dispatch can prove problematic as it can introduce resource contention, or at worst deadlocks, if you're not very careful about how you're starting your task.

Example:

  • Main thread calls a lower layer of code, which is using a dispatch queue to process operations
  • An item in that queue is already processing an item which happens to call beginBackgroundTask()

If the operation being performed on the main thread is synchronous, you get a deadlock. If the operation is asynchronous, you can still run into a delay if your background queue performs a lot of operations, as each one briefly is blocking the main queue each time.

The docs for beginBackgroundTask() claim that invoking the API is asynchronous, or that you can call this method at any time, but that doesn't appear to actually be the case.

Was this by design? Is beginBackgroundTask() intended to be used very sparingly?

Alas this is a bug on our side. While most of UIApplication does require main thread access, the background task methods do not. Unfortunately we failed to annotate them correctly for this purpose. These methods are safe to call from any thread and we do not expect clients to use them sparingly (although they aren't cheap, but not so expensive you should avoid them).

Your best solution would be to create wrapper functions in an Obj-C file that call into this functions. Since Obj-C will not check or trampoline these functions to the main thread, you only need to ensure they are marked correctly so that Swift will allow you to call them from any actor/thread without doing the same. Doing this will break the automatic naming (that often helps with debugging) so you will want to use UIApplication.beginBackgroundTask(withName:expirationHandler:) if that information has been useful to you.

We would also appreciate a feedback report about this issue, if only so you can be informed of the eventually resolution.

Hi,

Thanks for the prompt response and confirming. We were baffled after profiling the app after various customer complaints. I’ll go ahead with a feedback report for our organization.

Patrick

Is beginBackgroundTask() expected to dispatch to main?
 
 
Q