- O XAsyncBlock carrega todas as informações relacionadas à tarefa assíncrona e ao callback de conclusão.
- O XTaskQueueHandle permite determinar qual thread executa a tarefa assíncrona e qual thread chama o callback de conclusão do XAsyncBlock.
O XAsyncBlock
Vamos examinar o XAsyncBlock em detalhes. Ele é uma struct definida da seguinte forma:- queue - um XTaskQueueHandle, que é um identificador que representa informações sobre onde executar uma parte do trabalho. Se não for definido, uma fila padrão será usada.
- context - permite passar dados para a função de callback.
- callback - uma função de callback opcional que será chamada depois que o trabalho assíncrono for concluído. Se você não especificar um callback, poderá aguardar a conclusão do XAsyncBlock com XAsyncGetStatus e, em seguida, obter os resultados.
Importante: Um XAsyncBlock precisa permanecer na memória até que a tarefa assíncrona seja concluída. Se ele for alocado dinamicamente, poderá ser excluído dentro do callback de conclusão do XAsyncBlock.
Aguardando uma tarefa assíncrona
Você pode saber que uma tarefa assíncrona foi concluída de várias maneiras diferentes:- O callback de conclusão do XAsyncBlock é chamado.
- Chame XAsyncGetStatus com true para aguardar até que ela seja concluída.
Obtendo o resultado da tarefa assíncrona
Para obter o resultado, a maioria das funções de API assíncrona tem uma função [Nome da função]Result correspondente para receber o resultado da chamada assíncrona. No nosso código de exemplo, XblProfileGetUserProfileAsync tem uma função XblProfileGetUserProfileResult correspondente. Você pode usar essa função para recuperar o resultado da função e agir de acordo. Para obter detalhes completos sobre como recuperar resultados, consulte a documentação de cada função de API assíncrona.O XTaskQueueHandle
O XTaskQueueHandle permite determinar qual thread executa a tarefa assíncrona e qual thread chama o callback de conclusão do XAsyncBlock. Você pode controlar qual thread executa essas operações definindo um modo de despacho. Há três modos de despacho disponíveis:- Manual - As filas manuais não são despachadas automaticamente. Cabe ao desenvolvedor despachá-las em qualquer thread que desejar. Isso pode ser usado para atribuir o lado de trabalho ou o lado de callback de uma chamada assíncrona a uma thread específica. Isso é discutido em mais detalhes abaixo.
- Thread Pool - Despacha usando um pool de threads. O pool de threads invoca as chamadas em paralelo, retirando da fila uma chamada para executar à medida que as threads do pool ficam disponíveis. É o mais fácil de usar, mas oferece o menor controle sobre qual thread é usada.
- Serialized Thread Pool - Despacha usando um pool de threads. O pool de threads invoca as chamadas em série, retirando da fila uma chamada para executar à medida que a única thread do pool fica disponível.
- Immediate - Despacha imediatamente o trabalho enfileirado na thread a partir da qual ele foi enviado.
XTaskQueueDispatchMode.
Há três valores possíveis para XTaskQueueDispatchMode:
Despachando manualmente um XTaskQueueHandle
Se você usou o modo de despacho de fila manual para uma fila de trabalho ou de conclusão de um XTaskQueueHandle, precisará despachá-la manualmente. Digamos que um XTaskQueueHandle tenha sido criado com a fila de trabalho e a fila de conclusão definidas para despacho manual, assim:- queue - a fila na qual o trabalho será despachado.
- port - uma instância do enum XTaskQueuePort.
- timeoutInMs - um uint32_t para o tempo limite em milissegundos.
Quando chamar XTaskQueueDispatch
Para verificar quando a fila recebeu um novo item, você pode chamar XTaskQueueRegisterMonitor para definir um manipulador de eventos que informe ao seu código que há trabalhos ou conclusões prontos para serem despachados.- queue - a fila assíncrona para a qual você está enviando o callback.
- callbackContext - um ponteiro para os dados que devem ser passados para o callback de envio.
- callback - a função que será invocada quando um novo callback for enviado para a fila.
- token - um token que será usado em uma chamada posterior a XTaskQueueUnregisterMonitor para remover o callback.
XTaskQueueRegisterMonitor(queue, nullptr, HandleAsyncQueueCallback, &m_callbackToken);
O callback XTaskQueueMonitorCallback correspondente pode ser implementado da seguinte forma:
