> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# XTaskQueueTerminate

> XTaskQueueTerminate

# XTaskQueueTerminate

Encerra uma fila de tarefas cancelando todos os itens pendentes e impedindo que novos itens sejam enfileirados.

## Sintaxe

```cpp theme={null}
HRESULT XTaskQueueTerminate(  
         XTaskQueueHandle queue,  
         bool wait,  
         void* callbackContext,  
         XTaskQueueTerminatedCallback* callback  
)  
```

### Parâmetros

*queue*   \_In\_\
Tipo: XTaskQueueHandle

A fila a ser encerrada.

*wait*   \_In\_\
Tipo: bool

True para aguardar a conclusão do encerramento.

*callbackContext*   \_In\_opt\_\
Tipo: void\*

Um ponteiro de contexto opcional a ser passado para o retorno de chamada.

*callback*   \_In\_opt\_\
Tipo: XTaskQueueTerminatedCallback\*

Um retorno de chamada opcional que será chamado quando a fila for encerrada.

### Valor retornado

Tipo: HRESULT

Código de sucesso ou de erro HRESULT.

## Comentários

<Note>Não é seguro chamar esta função em um thread sensível ao tempo. Para obter mais informações, consulte [Threads sensíveis ao tempo](https://learn.microsoft.com/gaming/gdk/docs/gdk-dev/console-dev/overviews/threads/time-sensitive-threads).</Note>

[XTaskQueueCloseHandle](/pt-BR/reference/system/xtaskqueue/functions/xtaskqueueclosehandle) simplesmente decrementa uma contagem de referências interna no objeto da fila de tarefas. Se ainda houver retornos de chamada na fila, esses retornos de chamada mantêm uma referência ao objeto da fila e ainda podem ser chamados. Isso pode ser um problema no desligamento do aplicativo. Quando um aplicativo é desligado, ele precisa garantir que nenhum retorno de chamada indesejado seja executado após a limpeza. XTaskQueue fornece a API **XTaskQueueTerminate** para executar um encerramento controlado de uma fila.

Encerrar uma fila de tarefas executa as seguintes operações:

1. Todos os retornos de chamada das duas portas serão invocados com o parâmetro *canceled* definido como true.
2. Todos os retornos de chamada pendentes na porta de trabalho serão expedidos. O envio de novos retornos de chamada para a porta de trabalho falhará com E\_ABORT.
3. Todos os retornos de chamada pendentes na porta de conclusão serão expedidos. O envio de novos retornos de chamada para a porta de conclusão falhará com E\_ABORT.

Após a conclusão desse processo, **XTaskQueueTerminate** retornará se wait for true. Se wait for false, o encerramento ocorrerá de forma assíncrona. Se você fornecer um retorno de chamada de encerramento, ele será invocado a partir do thread de conclusão no final do encerramento.

<Note />

* **XTaskQueueTerminate** não fecha o identificador da fila. Após o encerramento, você ainda precisa chamar [XTaskQueueCloseHandle](/pt-BR/reference/system/xtaskqueue/functions/xtaskqueueclosehandle).
* Se você chamar **XTaskQueueTerminate** em um thread que está atendendo retornos de chamada da fila chamando [XTaskQueueDispatch](/pt-BR/reference/system/xtaskqueue/functions/xtaskqueuedispatch), não passe true para o parâmetro wait, ou seu código poderá entrar em deadlock.

O exemplo a seguir demonstra como encerrar uma fila de tarefas criada anteriormente.

<Note>**SubmitCallback** é uma função auxiliar definida no exemplo de código da função [XTaskQueueSubmitCallback](/pt-BR/reference/system/xtaskqueue/functions/xtaskqueuesubmitcallback).</Note>

```cpp theme={null}
void CreatingTaskQueue()
{
    XTaskQueueHandle queue;
    HRESULT hr = XTaskQueueCreate(XTaskQueueDispatchMode::ThreadPool, XTaskQueueDispatchMode::ThreadPool, &queue);
    if (FAILED(hr))
    {
        printf("Creating queue failed: 0x%x\r\n", hr);
        return;
    }

    SubmitCallbacks(queue);

    // Wait a while for the callbacks to run
    Sleep(1000);

    XTaskQueueTerminate(queue, true, nullptr, nullptr);
}
```

Uma fila de tarefas pode ser integrada a um thread de interface do usuário. Normalmente, você desejaria que os retornos de chamada enfileirados na porta de conclusão fossem executados no thread de interface do usuário. Este exemplo usa o pool de threads para o trabalho, mas integra os retornos de chamada da porta de conclusão a um Window Proc do Win32. Ele também demonstra o encerramento correto de uma fila de tarefas ao integrá-la a outro modelo de threading.

```cpp theme={null}
struct WorkData
{
    HWND hwnd;
    WCHAR text[80];
};

void CALLBACK WorkCompletion(void* context, bool cancel)
{
    WorkData* data = (WorkData*)context;

    if (!cancel)
    {
        SetWindowText(data->hwnd, data->text);
    }

    delete data;
}

void CALLBACK BackgroundWork(void* context, bool cancel)
{
    if (!cancel)
    {
        WorkData* data = new WorkData;
        data->hwnd = (HWND)context;

        if (GetTimeFormatEx(
            LOCALE_NAME_USER_DEFAULT, 0, nullptr, 
            nullptr, data->text, 80) == 0)
        {
            swprintf_s(data->text, L"Error : %d", GetLastError());
        }

        // Now take our formatted string and submit it as a completion callback
        XTaskQueueSubmitCallback(
            g_queue,
            XTaskQueuePort::Completion, 
            data, 
            WorkCompletion);
    }
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    HRESULT hr;

    switch (msg)
    {
    case WM_CREATE:
        
        // We will do work on the thread pool, but completion
        // callbacks should be manual so we can integrate them with
        // the message loop.

        hr = XTaskQueueCreate(
            XTaskQueueDispatchMode::ThreadPool,
            XTaskQueueDispatchMode::Manual,
            &g_queue);

        if (SUCCEEDED(hr))
        {
            hr = XTaskQueueRegisterMonitor(g_queue, hwnd, 
                [](void* context, XTaskQueueHandle, XTaskQueuePort port)
            {
                // If a new callback was submitted to the completion port, post a message
                // so we dispatch it in our message loop
                if (port == XTaskQueuePort::Completion)
                {
                    HWND hwnd = static_cast<HWND>(context);
                    PostMessage(hwnd, WM_QUEUE_COMPLETION, 0, 0);
                }
            }, &g_monitorToken);
        }

        if (FAILED(hr))
        {
            PostQuitMessage(1);
            return 0;
        }
        break;
      
    case WM_LBUTTONDOWN:
        hr = XTaskQueueSubmitCallback(
            g_queue,
            XTaskQueuePort::Completion,
            hwnd,
            BackgroundWork);

        if (FAILED(hr))
        {
            MessageBox(hwnd, L"Failed to submit callback.", L"Error", MB_OK);
        }
        break;

    case WM_QUEUE_COMPLETION:
        XTaskQueueDispatch(g_queue, XTaskQueuePort::Completion, 0);
        break;

    case WM_CLOSE:

        // Terminate the task queue.  When done, destroy our window.  The termination callback
        // is queued to the completion port, so it will already be on the UI thread.

        hr = XTaskQueueTerminate(g_queue, false, hwnd, [](void* context)
        {
            HWND hwnd = static_cast<HWND>(context);
            DestroyWindow(hwnd);
            XTaskQueueUnregisterMonitor(g_queue, g_monitorToken);
            XTaskQueueCloseHandle(g_queue);
        });

        if (SUCCEEDED(hr))
        {
            // Prevent DefWndProc from destroying our window because
            // the termination callback will do it.
            return 0;
        }
        break;

    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    }

    return DefWindowProc(hwnd, msg, wParam, lParam);
}

void TestWndProc()
{
    WNDCLASS wndClass;
    ZeroMemory(&wndClass, sizeof(wndClass));
    wndClass.lpfnWndProc = WndProc;
    wndClass.lpszClassName = L"TestClass";
    wndClass.hInstance = GetModuleHandle(nullptr);
    wndClass.hbrBackground = GetSysColorBrush(COLOR_WINDOW);

    ATOM c = RegisterClass(&wndClass);

    HWND h = CreateWindow(L"TestClass", L"Window", 
        WS_OVERLAPPEDWINDOW | WS_VISIBLE, 
        10, 10, 300, 100, nullptr, nullptr, 
        GetModuleHandle(nullptr), 0);

    if (!h)
    {
        return;
    }

    MSG m;

    while (GetMessage(&m, nullptr, 0, 0))
    {
        TranslateMessage(&m);
        DispatchMessage(&m);
    }
}
```

## Requisitos

**Cabeçalho:** XTaskQueue.h

**Biblioteca:** xgameruntime.lib

**Plataformas compatíveis:** Windows, consoles da família XBOX One e consoles XBOX Series

## Documentação conceitual

* [Limpar a fila de tarefas](/pt-BR/build/core-features/common/async/async-libraries/async-library-xtaskqueue-example-cleanup-task-queue)
* [Threads sensíveis ao tempo](https://learn.microsoft.com/gaming/gdk/docs/gdk-dev/console-dev/overviews/threads/time-sensitive-threads)

## Confira também

[Membros de XTaskQueue](/pt-BR/reference/system/xtaskqueue/xtaskqueue_members)\
[Modelo de programação assíncrona](/pt-BR/build/core-features/common/async/async-programming-model)\
[Design da fila de tarefas assíncrona](/pt-BR/build/core-features/common/async/async-task-queue-design)


## Related topics

- [XTaskQueueTerminate](/reference/system/xtaskqueue/functions/xtaskqueueterminate.md)
- [XTaskQueueTerminatedCallback](/reference/system/xtaskqueue/functions/xtaskqueueterminatedcallback.md)
