Gewusst wie: Verwalten einer Planerinstanz

Mit Planerinstanzen können Sie bestimmte Planungsrichtlinien verschiedenen Arten von Arbeitslasten zuordnen. Dieses Thema enthält zwei grundlegende Beispiele, die zeigen, wie eine Planerinstanz erstellt und verwaltet wird.

In den Beispielen werden Planer erstellt, die die standardmäßigen Planerrichtlinien verwenden. Ein Beispiel für die Erstellung eines Planers, der eine benutzerdefinierte Richtlinie verwendet, finden Sie unter Gewusst wie: Angeben von bestimmten Planerrichtlinien.

So verwalten Sie eine Planerinstanz in der Anwendung

  1. Erstellen Sie ein Concurrency::SchedulerPolicy-Objekt, das die Richtlinienwerte für den zu verwendenden Planer enthält.

  2. Rufen Sie die Concurrency::CurrentScheduler::Create-Methode oder die Concurrency::Scheduler::Create-Methode auf, um eine Planerinstanz zu erstellen.

    Wenn Sie die Scheduler::Create-Methode verwenden, rufen Sie die Concurrency::Scheduler::Attach-Methode auf, wenn Sie den Planer dem aktuellen Kontext zuordnen müssen.

  3. Rufen Sie die CreateEvent-Funktion auf, um ein Handle für ein nicht signalisiertes automatisches Zurücksetzungobjekt zu erstellen.

  4. Übergeben Sie das Handle für das Ereignisobjekt, das Sie gerade erstellt haben, an die Concurrency::CurrentScheduler::RegisterShutdownEvent-Methode oder die Concurrency::Scheduler::RegisterShutdownEvent-Methode. Hierdurch wird das Ereignis als festzulegen registriert, wenn der Planer zerstört wird.

  5. Führen Sie die Aufgaben aus, die vom aktuellen Planer geplant werden sollen.

  6. Rufen Sie die Concurrency::CurrentScheduler::Detach-Methode auf, um den aktuellen Planer abzutrennen und den vorherigen Planer als aktuellen Planer wiederherzustellen.

    Wenn Sie die Scheduler::Create-Methode verwenden, rufen Sie die Concurrency::Scheduler::Release-Methode auf, um den Verweiszähler des Scheduler-Objekts zu dekrementieren.

  7. Übergeben Sie das Handle für das Ereignis an die WaitForSingleObject-Funktion, um zu warten, bis der Planer herunterfährt.

  8. Rufen Sie die CloseHandle-Funktion auf, um das Handle für das Ereignisobjekt zu schließen.

Beispiel

Der folgende Code veranschaulicht zwei Möglichkeiten für die Verwaltung einer Planerinstanz. In jedem Beispiel wird zunächst mit dem Standardplaner eine Aufgabe ausgeführt, die den eindeutigen Bezeichner des aktuellen Planers ausgibt. Jedes Beispiel verwendet dann eine Planerinstanz, um die gleiche Aufgabe noch einmal auszuführen. In jedem Beispiel wird schließlich der Standardplaner als aktueller Planer wiederhergestellt und die Aufgabe noch einmal ausgeführt.

Im ersten Beispiel wird die Concurrency::CurrentScheduler-Klasse verwendet, um eine Planerinstanz zu erstellen und sie dem aktuellen Kontext zuzuordnen. Das zweite Beispiel führt die gleiche Aufgabe mithilfe der Concurrency::Scheduler-Klasse aus. In der Regel wird die CurrentScheduler-Klasse verwendet, um mit dem aktuellen Planer zu arbeiten. Das zweite Beispiel, das die Scheduler-Klasse verwendet, ist nützlich, wenn Sie steuern möchten, wann der Planer dem aktuellen Kontext zugeordnet wird, oder wenn Sie bestimmte Planer bestimmten Aufgaben zuordnen möchten.

// scheduler-instance.cpp
// compile with: /EHsc
#include <windows.h>
#include <ppl.h>
#include <iostream>

using namespace Concurrency;
using namespace std;

// Prints the identifier of the current scheduler to the console.
void perform_task()
{
   // A task group.
   task_group tasks;

   // Run a task in the group. The current scheduler schedules the task.
   tasks.run_and_wait([] { 
      wcout << L"Current scheduler id: " << CurrentScheduler::Id() << endl;
   });
}

// Uses the CurrentScheduler class to manage a scheduler instance.
void current_scheduler()
{
   // Run the task.
   // This prints the identifier of the default scheduler.
   perform_task();

   // For demonstration, create a scheduler object that uses 
   // the default policy values.
   wcout << L"Creating and attaching scheduler..." << endl;
   CurrentScheduler::Create(SchedulerPolicy());

   // Register to be notified when the scheduler shuts down.
   HANDLE hShutdownEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
   CurrentScheduler::RegisterShutdownEvent(hShutdownEvent);

   // Run the task again.
   // This prints the identifier of the new scheduler.
   perform_task();

   // Detach the current scheduler. This restores the previous scheduler
   // as the current one.
   wcout << L"Detaching scheduler..." << endl;
   CurrentScheduler::Detach();

   // Wait for the scheduler to shut down and destroy itself.
   WaitForSingleObject(hShutdownEvent, INFINITE);

   // Close the event handle.
   CloseHandle(hShutdownEvent);

   // Run the sample task again.
   // This prints the identifier of the default scheduler.
   perform_task();
}

// Uses the Scheduler class to manage a scheduler instance.
void explicit_scheduler()
{
   // Run the task.
   // This prints the identifier of the default scheduler.
   perform_task();

   // For demonstration, create a scheduler object that uses 
   // the default policy values.
   wcout << L"Creating scheduler..." << endl;
   Scheduler* scheduler = Scheduler::Create(SchedulerPolicy());

   // Register to be notified when the scheduler shuts down.
   HANDLE hShutdownEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
   scheduler->RegisterShutdownEvent(hShutdownEvent);

   // Associate the scheduler with the current thread.
   wcout << L"Attaching scheduler..." << endl;
   scheduler->Attach();

   // Run the sample task again.
   // This prints the identifier of the new scheduler.
   perform_task();

   // Detach the current scheduler. This restores the previous scheduler
   // as the current one.
   wcout << L"Detaching scheduler..." << endl;
   CurrentScheduler::Detach();

   // Release the final reference to the scheduler. This causes the scheduler
   // to shut down after all tasks finish.
   scheduler->Release();

   // Wait for the scheduler to shut down and destroy itself.
   WaitForSingleObject(hShutdownEvent, INFINITE);

   // Close the event handle.
   CloseHandle(hShutdownEvent);

   // Run the sample task again.
   // This prints the identifier of the default scheduler.
   perform_task();
}

int wmain()
{
   // Use the CurrentScheduler class to manage a scheduler instance.
   wcout << L"Using CurrentScheduler class..." << endl << endl;
   current_scheduler();

   wcout << endl << endl;

   // Use the Scheduler class to manage a scheduler instance.
   wcout << L"Using Scheduler class..." << endl << endl;
   explicit_scheduler();
}

Folgende Ergebnisse werden zurückgegeben:

Using CurrentScheduler class...

Current scheduler id: 0
Creating and attaching scheduler...
Current scheduler id: 1
Detaching scheduler...
Current scheduler id: 0


Using Scheduler class...

Current scheduler id: 0
Creating scheduler...
Attaching scheduler...
Current scheduler id: 2
Detaching scheduler...
Current scheduler id: 0

Kompilieren des Codes

Kopieren Sie den Beispielcode, und fügen Sie ihn in ein Visual Studio-Projekt ein, oder fügen Sie ihn in eine Datei mit dem Namen scheduler-instance.cpp ein, und führen Sie dann den folgenden Befehl in einem Visual Studio 2010-Eingabeaufforderungsfenster aus.

cl.exe /EHsc scheduler-instance.cpp

Siehe auch

Aufgaben

Gewusst wie: Angeben von bestimmten Planerrichtlinien

Weitere Ressourcen

Planerinstanzen