Pular para o conteúdo principal
Uma API assíncrona é uma API que retorna rapidamente, mas inicia uma tarefa assíncrona, e o resultado é retornado depois que a tarefa é concluída. Tradicionalmente, os jogos têm pouco controle sobre qual thread executa a tarefa assíncrona e qual thread retorna os resultados ao usar um callback de conclusão. Alguns jogos são projetados para que uma seção do heap seja acessada por apenas uma thread, a fim de evitar qualquer necessidade de sincronização de threads. Se o callback de conclusão não for chamado a partir de uma thread controlada pelo jogo, atualizar o estado compartilhado com o resultado de uma tarefa assíncrona exigirá sincronização de threads. O SDK unificado do PlayFab expõe uma API C assíncrona que dá aos desenvolvedores controle direto das threads ao fazer uma chamada à API assíncrona. Aqui está um exemplo básico que chama PFProfilesGetProfileAsync:
Para entender esse padrão de chamada, você precisa entender como usar o XAsyncBlock e o XTaskQueueHandle. 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:
O XAsyncBlock contém:
  • queue - um XTaskQueueHandle, que é um identificador que representa informações sobre onde executar uma parte do trabalho. Se esse parâmetro 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.
Você deve criar um novo XAsyncBlock no heap para cada chamada assíncrona que fizer. O XAsyncBlock precisa existir até que o callback de conclusão do XAsyncBlock seja chamado; depois disso, ele pode ser excluído.
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 duas maneiras diferentes:
  • O callback de conclusão do XAsyncBlock é chamado.
  • Chame XAsyncGetStatus com true para aguardar até que ela seja concluída.
Com XAsyncGetStatus, a tarefa assíncrona é considerada concluída depois que o callback de conclusão do XAsyncBlock é executado; no entanto, o callback de conclusão do XAsyncBlock é opcional. Depois que a tarefa assíncrona for concluída, você poderá obter os resultados.

Obtendo o resultado da tarefa assíncrona

Para obter o resultado, a maioria das funções de API assíncronas tem uma função Result correspondente para receber o resultado da chamada assíncrona. No nosso código de exemplo, PFProfilesGetProfileAsync tem uma função PFProfilesGetProfileGetResult 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 - A fila manual não é despachada automaticamente. Cabe ao desenvolvedor despachá-la 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.
  • 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 Thread Pool é 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.
Para criar um novo XTaskQueueHandle, você precisa chamar XTaskQueueCreate. Por exemplo:
Essa função recebe dois parâmetros XTaskQueueDispatchMode. Há três valores possíveis para XTaskQueueDispatchMode:
workDispatchMode determina o modo de despacho da thread que processa o trabalho assíncrono. completionDispatchMode determina o modo de despacho da thread que processa a conclusão da operação assíncrona. Depois de criar seu XTaskQueueHandle, basta adicioná-lo ao XAsyncBlock para controlar as threads das suas funções de trabalho e de conclusão. Quando terminar de usar o XTaskQueueHandle, normalmente quando o jogo estiver terminando, você poderá fechá-lo com XTaskQueueCloseHandle:
Exemplo de chamada:

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:
Para despachar o trabalho que recebeu XTaskQueueDispatchMode::Manual, chame a função XTaskQueueDispatch.
Exemplo de chamada:
  • 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.
Há dois tipos de callback definidos pelo enum XTaskQueuePort:

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.
XTaskQueueRegisterMonitor recebe os seguintes parâmetros:
  • 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 invocada quando um novo callback é enviado para a fila.
  • token - um token usado em uma chamada posterior a XTaskQueueUnregisterMonitor para remover o callback.
Por exemplo, aqui está uma chamada a XTaskQueueRegisterMonitor:
O callback XTaskQueueMonitorCallback correspondente pode ser implementado da seguinte forma:
Em seguida, em uma thread em segundo plano, você pode aguardar que essa variável de condição seja acionada e chamar XTaskQueueDispatch.

Confira também

Última modificação em 8 de outubro de 2026