The XAsyncBlock
Let’s take a look at the XAsyncBlock in detail. It’s a struct defined as follows:- queue - an XTaskQueueHandle which is a handle representing information about where to run a piece of work. If this parameter isn’t set, a default queue is used.
- context - allows you to pass data to the callback function.
- callback - an optional callback function that will be called after the asynchronous work has been done. If you don’t specify a callback, you can wait for the XAsyncBlock to complete with XAsyncGetStatus, and then get the results.
Important: An XAsyncBlock must remain in memory until the asynchronous task completes. If it is dynamically allocated, it can be deleted inside the XAsyncBlock’s completion callback.
Waiting for an asynchronous task
You can tell an asynchronous task is complete in two different ways:- The XAsyncBlock’s completion callback is called.
- Call XAsyncGetStatus with true to wait until it completes.
Getting the result of the asynchronous task
To get the result, most asynchronous API functions have a corresponding Result function to receive the result of the asynchronous call. In our example code, PFProfilesGetProfileAsync has a corresponding PFProfilesGetProfileGetResult function. You can use this function to retrieve the result of the function and act accordingly. For full details on retrieving results, see the documentation of each asynchronous API function.The XTaskQueueHandle
The XTaskQueueHandle allows you to determine which thread executes the asynchronous task and which thread calls the XAsyncBlock’s completion callback. You can control which thread performs these operations by setting a dispatch mode. There are three dispatch modes available:- Manual - The manual queue isn’t automatically dispatched. It’s up to the developer to dispatch them on any thread they want. This can be used to assign either the work or callback side of an async call to a specific thread.
- Thread Pool - Dispatches using a thread pool. The thread pool invokes the calls in parallel, taking a call to execute from the queue in turn as thread pool threads become available. Thread Pool is the easiest to use, but gives you the least amount of control over which thread is used.
- Serialized Thread Pool - Dispatches using a thread pool. The thread pool invokes the calls in serial, taking a call to execute from the queue in turn as the single thread pool thread becomes available.
- Immediate - Immediately dispatches the queued work on the thread from which it was submitted.
Manually dispatching an XTaskQueueHandle
If you used the manual queue dispatch mode for an XTaskQueueHandle work or completion queue, you need to manually dispatch. Let’s say that an XTaskQueueHandle was created where both the work queue and the completion queue are set to dispatch manually like so:- queue - which queue to dispatch work on.
- port - an instance of the XTaskQueuePort enum.
- timeoutInMs - a uint32_t for the timeout in milliseconds.
When to call XTaskQueueDispatch
In order to check when the queue has received a new item, you can call XTaskQueueRegisterMonitor to set an event handler to let your code know that either work or completions are ready to be dispatched.- queue - the async queue you’re submitting the callback for.
- callbackContext - a pointer to data that should be passed to the submit callback.
- callback - the function invoked when a new callback is submitted to the queue.
- token - a token used in a later call to XTaskQueueUnregisterMonitor to remove the callback.
