> ## 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

Finaliza una cola de tareas cancelando todos los elementos pendientes e impidiendo que se pongan en cola nuevos elementos.

## Sintaxis

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

### Parámetros

*queue*   \_In\_\
Tipo: XTaskQueueHandle

La cola que se finalizará.

*wait*   \_In\_\
Tipo: bool

True para esperar a que se complete la finalización.

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

Un puntero de contexto opcional que se pasará a la devolución de llamada.

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

Una devolución de llamada opcional que se llamará cuando la cola haya finalizado.

### Valor devuelto

Tipo: HRESULT

Código de error o de éxito HRESULT.

## Comentarios

<Note>No es seguro llamar a esta función en un subproceso sensible al tiempo. Para obtener más información, consulte [Subprocesos sensibles al tiempo](https://learn.microsoft.com/gaming/gdk/docs/gdk-dev/console-dev/overviews/threads/time-sensitive-threads).</Note>

[XTaskQueueCloseHandle](/reference/system/xtaskqueue/functions/xtaskqueueclosehandle) simplemente disminuye un recuento de referencias interno en el objeto de cola de tareas. Si todavía hay devoluciones de llamada en la cola, esas devoluciones de llamada mantienen una referencia al objeto de cola y es posible que todavía se llamen. Esto puede suponer un problema para el cierre de la aplicación. Cuando una aplicación se cierra, deberá asegurarse de que no se ejecutan devoluciones de llamada espurias después de la limpieza. XTaskQueue proporciona la API **XTaskQueueTerminate** para realizar una finalización controlada de una cola.

Finalizar una cola de tareas realiza las siguientes operaciones:

1. Todas las devoluciones de llamada de ambos puertos se invocarán con su parámetro *canceled* establecido en true.
2. Se distribuirán todas las devoluciones de llamada pendientes en el puerto de trabajo. El envío de nuevas devoluciones de llamada al puerto de trabajo producirá un error E\_ABORT.
3. Se distribuirán todas las devoluciones de llamada pendientes en el puerto de finalización. El envío de nuevas devoluciones de llamada al puerto de finalización producirá un error E\_ABORT.

Una vez completado este proceso, **XTaskQueueTerminate** regresará si wait es true. Si wait es false, la finalización se produce de forma asincrónica. Si proporciona una devolución de llamada de finalización, se invocará desde el subproceso de finalización al final de la finalización.

<Note />

* **XTaskQueueTerminate** no cierra el identificador de la cola. Después de finalizar, todavía debe llamar a [XTaskQueueCloseHandle](/reference/system/xtaskqueue/functions/xtaskqueueclosehandle).
* Si llama a **XTaskQueueTerminate** en un subproceso que está atendiendo devoluciones de llamada de la cola mediante llamadas a [XTaskQueueDispatch](/reference/system/xtaskqueue/functions/xtaskqueuedispatch), no pase true para el parámetro wait o el código podría interbloquearse.

En el ejemplo siguiente se muestra cómo finalizar una cola de tareas creada anteriormente.

<Note>**SubmitCallback** es una función auxiliar que se define en el ejemplo de código de la función [XTaskQueueSubmitCallback](/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);
}
```

Una cola de tareas se puede integrar con un subproceso de interfaz de usuario. Normalmente, querrá que las devoluciones de llamada en cola en el puerto de finalización se ejecuten en el subproceso de interfaz de usuario. En este ejemplo se usa el grupo de subprocesos para el trabajo, pero se integran las devoluciones de llamada del puerto de finalización en un Window Proc de Win32. También se muestra la finalización correcta de una cola de tareas al integrarla con otro modelo de subprocesos.

```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

**Encabezado:** XTaskQueue.h

**Biblioteca:** xgameruntime.lib

**Plataformas compatibles:** Windows, consolas de la familia XBOX One y consolas XBOX Series

## Documentación conceptual

* [Limpiar la cola de tareas](/build/core-features/common/async/async-libraries/async-library-xtaskqueue-example-cleanup-task-queue)
* [Subprocesos sensibles al tiempo](https://learn.microsoft.com/gaming/gdk/docs/gdk-dev/console-dev/overviews/threads/time-sensitive-threads)

## Consulte también

[Miembros de XTaskQueue](/reference/system/xtaskqueue/xtaskqueue_members)\
[Modelo de programación asincrónica](/build/core-features/common/async/async-programming-model)\
[Diseño de la cola de tareas asincrónicas](/build/core-features/common/async/async-task-queue-design)


## Related topics

- [XTaskQueueTerminatedCallback](/es/reference/system/xtaskqueue/functions/xtaskqueueterminatedcallback.md)
- [XTaskQueueCloseHandle](/es/reference/system/xtaskqueue/functions/xtaskqueueclosehandle.md)
- [XTaskQueueCallback](/es/reference/system/xtaskqueue/functions/xtaskqueuecallback.md)
- [XTaskQueue](/es/reference/system/xtaskqueue/xtaskqueue_members.md)
- [Ejemplo de limpieza de una cola de tareas](/es/build/core-features/common/async/async-libraries/async-library-xtaskqueue-example-cleanup-task-queue.md)
