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

Termine une file d'attente de tâches en annulant tous les éléments en attente et en empêchant la mise en file d'attente de nouveaux éléments.

## Syntaxe

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

### Paramètres

*queue*   \_In\_\
Type : XTaskQueueHandle

File d'attente à terminer.

*wait*   \_In\_\
Type : bool

True pour attendre la fin de la terminaison.

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

Pointeur de contexte facultatif à passer au rappel.

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

Rappel facultatif qui sera appelé lorsque la file d'attente aura été terminée.

### Valeur de retour

Type : HRESULT

Code de réussite ou d'erreur HRESULT.

## Remarques

<Note>Cette fonction ne peut pas être appelée en toute sécurité sur un thread sensible au temps. Pour plus d'informations, consultez [Threads sensibles au temps](https://learn.microsoft.com/gaming/gdk/docs/gdk-dev/console-dev/overviews/threads/time-sensitive-threads).</Note>

[XTaskQueueCloseHandle](/fr-CA/reference/system/xtaskqueue/functions/xtaskqueueclosehandle) se contente de décrémenter un décompte de références interne sur l'objet file d'attente de tâches. S'il reste des rappels dans la file d'attente, ces rappels détiennent une référence sur l'objet file d'attente et peuvent encore être appelés. Cela peut poser problème lors de l'arrêt de l'application. Lorsqu'une application s'arrête, elle doit s'assurer qu'aucun rappel intempestif ne s'exécute après le nettoyage. XTaskQueue fournit l'API **XTaskQueueTerminate** pour effectuer une terminaison contrôlée d'une file d'attente.

La terminaison d'une file d'attente de tâches effectue les opérations suivantes :

1. Tous les rappels des deux ports sont appelés avec leur paramètre *canceled* défini sur true.
2. Tous les rappels en attente sur le port de travail sont distribués. La soumission de nouveaux rappels au port de travail échoue avec E\_ABORT.
3. Tous les rappels en attente sur le port d'achèvement sont distribués. La soumission de nouveaux rappels au port d'achèvement échoue avec E\_ABORT.

Une fois ce processus terminé, **XTaskQueueTerminate** retourne si wait est true. Si wait est false, la terminaison se produit de façon asynchrone. Si vous fournissez un rappel de terminaison, il sera appelé à partir du thread d'achèvement à la fin de la terminaison.

<Note />

* **XTaskQueueTerminate** ne ferme pas le handle de la file d'attente. Après la terminaison, vous devez toujours appeler [XTaskQueueCloseHandle](/fr-CA/reference/system/xtaskqueue/functions/xtaskqueueclosehandle).
* Si vous appelez **XTaskQueueTerminate** sur un thread qui traite les rappels de la file d'attente en appelant [XTaskQueueDispatch](/fr-CA/reference/system/xtaskqueue/functions/xtaskqueuedispatch), ne passez pas true pour le paramètre wait, sinon votre code risque de se retrouver en interblocage.

L'exemple suivant montre comment terminer une file d'attente de tâches créée précédemment.

<Note>**SubmitCallback** est une fonction d'assistance définie dans l'exemple de code de la fonction [XTaskQueueSubmitCallback](/fr-CA/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);
}
```

Une file d'attente de tâches peut être intégrée à un thread d'interface utilisateur. En général, vous voudrez que les rappels mis en file d'attente sur le port d'achèvement s'exécutent sur le thread d'interface utilisateur. Cet exemple utilise le pool de threads pour le travail, mais intègre les rappels du port d'achèvement dans une procédure de fenêtre Win32. Il montre également comment terminer correctement une file d'attente de tâches lors de son intégration à un autre modèle de threads.

```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);
    }
}
```

## Configuration requise

**En-tête :** XTaskQueue.h

**Bibliothèque :** xgameruntime.lib

**Plateformes prises en charge :** Windows, consoles de la famille XBOX One et consoles XBOX Series

## Documentation conceptuelle

* [Nettoyer une file d'attente de tâches](/fr-CA/build/core-features/common/async/async-libraries/async-library-xtaskqueue-example-cleanup-task-queue)
* [Threads sensibles au temps](https://learn.microsoft.com/gaming/gdk/docs/gdk-dev/console-dev/overviews/threads/time-sensitive-threads)

## Voir aussi

[Membres de XTaskQueue](/fr-CA/reference/system/xtaskqueue/xtaskqueue_members)\
[Modèle de programmation asynchrone](/fr-CA/build/core-features/common/async/async-programming-model)\
[Conception de la file d'attente de tâches asynchrones](/fr-CA/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)
- [Clean up task queue example](/build/core-features/common/async/async-libraries/async-library-xtaskqueue-example-cleanup-task-queue.md)
- [XTaskQueueCloseHandle](/reference/system/xtaskqueue/functions/xtaskqueueclosehandle.md)
- [XTaskQueue](/reference/system/xtaskqueue/xtaskqueue_members.md)
