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

Arrête 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 à arrêter.

*wait*   \_In\_\
Type : bool

True pour attendre la fin de l'arrêt.

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

Pointeur de contexte facultatif à passer au rappel.

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

Rappel facultatif qui sera appelé une fois la file d'attente arrêtée.

### Valeur de retour

Type : HRESULT

Code de réussite ou d'erreur HRESULT.

## Remarques

<Note>Il n'est pas sûr d'appeler cette fonction sur un thread urgent. Pour plus d'informations, consultez [Threads urgents](https://learn.microsoft.com/gaming/gdk/docs/gdk-dev/console-dev/overviews/threads/time-sensitive-threads).</Note>

[XTaskQueueCloseHandle](/fr/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 parasite ne s'exécute après le nettoyage. XTaskQueue fournit l'API **XTaskQueueTerminate** pour effectuer un arrêt contrôlé d'une file d'attente.

L'arrêt d'une file d'attente de tâches effectue les opérations suivantes :

1. Tous les rappels des deux ports sont invoqué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 a la valeur true. Si wait a la valeur false, l'arrêt se produit de manière asynchrone. Si vous fournissez un rappel d'arrêt, il est invoqué à partir du thread d'achèvement à la fin de l'arrêt.

<Note />

* **XTaskQueueTerminate** ne ferme pas le handle de file d'attente. Après l'arrêt, vous devez toujours appeler [XTaskQueueCloseHandle](/fr/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/reference/system/xtaskqueue/functions/xtaskqueuedispatch), ne passez pas true pour le paramètre wait, sinon votre code risque de se bloquer (interblocage).

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

<Note>**SubmitCallback** est une fonction d'assistance définie dans l'exemple de code de la fonction [XTaskQueueSubmitCallback](/fr/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 souhaitez 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 (Window Proc) Win32. Il montre également l'arrêt correct d'une file d'attente de tâches lors de son intégration à un autre modèle 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);
    }
}
```

## 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/build/core-features/common/async/async-libraries/async-library-xtaskqueue-example-cleanup-task-queue)
* [Threads urgents](https://learn.microsoft.com/gaming/gdk/docs/gdk-dev/console-dev/overviews/threads/time-sensitive-threads)

## Voir aussi

[Membres XTaskQueue](/fr/reference/system/xtaskqueue/xtaskqueue_members)\
[Modèle de programmation asynchrone](/fr/build/core-features/common/async/async-programming-model)\
[Conception de la file d'attente de tâches asynchrones](/fr/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)
