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

# Procedimiento: Uso de una cola de tareas con un bucle de mensajes de Windows

> Procedimiento: Uso de una cola de tareas con un bucle de mensajes de Windows

## Ejemplo

Una cola de tareas puede integrarse con un bucle de mensajes de Windows. Normalmente, querrá que las devoluciones de llamada puestas en cola en el puerto de finalización se ejecuten en el mismo subproceso que el bucle de mensajes.

En el ejemplo siguiente se usa el grupo de subprocesos para el trabajo, pero se integran las devoluciones de llamada del puerto de finalización en un procedimiento de ventana de Win32. Este ejemplo también muestra la terminación correcta de una cola de tareas cuando se integra con otro modelo de subprocesos.

```c++ theme={null}
  
// Example of using a task queue and Window proc together.  
  
XTaskQueueHandle g_queue; 
XTaskQueueRegistrationToken g_monitorToken;  
  
// Posted when there's a completion callback.  
#define WM_QUEUE_COMPLETION (WM_USER + 1)  
  
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'll do work on the thread pool, but completion  
        // callbacks should be manual so that 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 that 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 this is 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);  
    }  
}  
```

## Consulte también

[Diseño de la cola de tareas](/build/core-features/common/async/async-task-queue-design)


## Related topics

- [Procedimiento: Uso de un elemento de espera de cola de tareas](/es/build/core-features/common/async/async-task-queue-design-howto/using-task-queue-waiter.md)
- [Procedimiento: Creación de una cola de tareas manual](/es/build/core-features/common/async/async-task-queue-design-howto/creating-manual-task-queue.md)
- [Procedimiento: Creación de una cola de tareas compuesta](/es/build/core-features/common/async/async-task-queue-design-howto/creating-composite-task-queue.md)
- [Procedimiento: Uso de la cola de tareas del proceso](/es/build/core-features/common/async/async-task-queue-design-howto/using-process-task-queue.md)
- [Procedimiento: Creación de una cola de tareas de grupo de subprocesos](/es/build/core-features/common/async/async-task-queue-design-howto/creating-thread-pool-task-queue.md)
