Procedura: gestire un'istanza dell'utilità di pianificazione

Le istanze dell'utilità di pianificazione consentono di associare criteri di pianificazione specifici a diversi tipi di carichi di lavoro. In questo argomento vengono forniti due esempi di base che illustrano come creare e gestire un'istanza dell'utilità di pianificazione.

Negli esempi vengono create utilità di pianificazione che utilizzano i criteri dell'utilità di pianificazione predefiniti. Per un esempio in cui viene creata un'utilità di pianificazione che utilizza criteri personalizzati, vedere Procedura: specificare criteri dell'utilità di pianificazione specifici.

Per gestire un'istanza dell'utilità di pianificazione nell'applicazione

  1. Creare un oggetto Concurrency::SchedulerPolicy contenente i valori dei criteri che devono essere utilizzati dall'utilità di pianificazione.

  2. Chiamare il metodo Concurrency::CurrentScheduler::Create o il metodo Concurrency::Scheduler::Create per creare un'istanza dell'utilità di pianificazione.

    Se si utilizza il metodo Scheduler::Create, chiamare il metodo Concurrency::Scheduler::Attach quando è necessario associare l'utilità di pianificazione al contesto corrente.

  3. Chiamare la funzione CreateEvent per creare un handle per un oggetto evento di reimpostazione automatica non segnalato.

  4. Passare l'handle per l'oggetto evento appena creato al metodo Concurrency::CurrentScheduler::RegisterShutdownEvent o al metodo Concurrency::Scheduler::RegisterShutdownEvent. In questo modo viene registrato l'evento da impostare quando viene eliminata l'utilità di pianificazione.

  5. Eseguire le attività che si desidera vengano pianificate dall'utilità di pianificazione corrente.

  6. Chiamare il metodo Concurrency::CurrentScheduler::Detach per disconnettere l'utilità di pianificazione corrente e ripristinare l'utilità di pianificazione precedente come utilità corrente.

    Se si utilizza il metodo Scheduler::Create, chiamare il metodo Concurrency::Scheduler::Release per decrementare il conteggio dei riferimenti dell'oggetto Scheduler.

  7. Passare l'handle per l'evento alla funzione WaitForSingleObject per attendere la chiusura dell'utilità di pianificazione.

  8. Chiamare la funzione CloseHandle per chiudere l'handle per l'oggetto evento.

Esempio

Nel codice seguente vengono illustrati due modi per gestire un'istanza dell'utilità di pianificazione. In ogni esempio viene innanzitutto utilizzata l'utilità di pianificazione predefinita per eseguire un'attività che stampa l'identificatore univoco dell'utilità di pianificazione corrente. Viene quindi utilizzata un'istanza dell'utilità di pianificazione per eseguire di nuovo la stessa attività. Infine, viene ripristinata l'utilità di pianificazione predefinita come utilità corrente e viene eseguita nuovamente l'attività.

Nel primo esempio viene utilizzata la classe Concurrency::CurrentScheduler per creare un'istanza dell'utilità di pianificazione e associarla al contesto corrente. Nel secondo esempio viene utilizzata la classe Concurrency::Scheduler per eseguire la stessa attività. In genere, la classe CurrentScheduler viene utilizzata per gestire l'utilità di pianificazione corrente. Il secondo esempio, in cui viene utilizzata la classe Scheduler, è utile se si desidera controllare quando l'utilità di pianificazione viene associata al contesto corrente o se si desidera associare utilità di pianificazione specifiche a specifiche attività.

// 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();
}

Questo esempio produce l'output che segue.

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

Compilazione del codice

Copiare il codice di esempio e incollarlo in un progetto di Visual Studio o incollarlo in un file denominato scheduler-instance.cpp, quindi eseguire il comando seguente in una finestra del prompt dei comandi di Visual Studio 2010.

cl.exe /EHsc scheduler-instance.cpp

Vedere anche

Attività

Procedura: specificare criteri dell'utilità di pianificazione specifici

Altre risorse

Istanze dell'utilità di pianificazione