Compartilhar via


Como gerenciar uma instância de agendador

As instâncias do agendador permitem associar políticas de agendamento específicas a vários tipos de cargas de trabalho. Este tópico contém dois exemplos básicos que mostram como criar e gerenciar uma instância do agendador.

Os exemplos criam agendadores que usam as políticas de agendador padrão. Para obter um exemplo que cria um Agendador que usa uma política personalizada, consulte Como: especificar políticas de agendador específicas.

Para gerenciar uma instância do agendador no aplicativo

  1. Crie um objeto concurrency::SchedulerPolicy que contém os valores de política para o agendador usar.

  2. Chame o método concurrency::CurrentScheduler::Create ou o método concurrency::Scheduler::Create para criar uma instância de agendador.

    Se você usar o método Scheduler::Create, chame o método concurrency::Scheduler::Attach quando precisar associar o agendador ao contexto atual.

  3. Chame a função CreateEvent para criar um identificador para um objeto de evento de redefinição automática não sinalizado.

  4. Passe o identificador para o objeto de evento que você acabou de criar para o método concurrency::CurrentScheduler::RegisterShutdownEvent ou para o método concurrency::Scheduler::RegisterShutdownEvent. Isso registra o evento a ser definido quando o agendador é destruído.

  5. Execute as tarefas que você deseja que o agendador atual agende.

  6. Chame o método concurrency::CurrentScheduler::Detach para desanexar o agendador atual e restaurar o agendador anterior como o atual.

    Se você usar o método Scheduler::Create, chame o método concurrency::Scheduler::Release se para decrementar a contagem de referência do objeto Scheduler.

  7. Passe o identificador para o evento para a função WaitForSingleObject para aguardar o agendador ser desligado.

  8. Chame a função CloseHandle para fechar o identificador do objeto de evento.

Exemplo

O código a seguir mostra duas maneiras de gerenciar uma instância do agendador. Cada exemplo primeiro usa o agendador padrão para executar uma tarefa que imprime o identificador exclusivo do agendador atual. Cada exemplo usa uma instância de agendador para executar a mesma tarefa novamente. Por fim, cada exemplo restaura o agendador padrão como o atual e executa a tarefa mais uma vez.

O primeiro exemplo usa a classe concurrency::CurrentScheduler para criar uma instância de agendador e associá-la ao contexto atual. O segundo exemplo usa a classe concurrency::Scheduler para executar a mesma tarefa. Normalmente, a classe CurrentScheduler é usada para trabalhar com o agendador atual. O segundo exemplo, que usa a classe Scheduler, é útil quando se deseja controlar quando o agendador está associado ao contexto atual ou quando se deseja associar agendadores específicos a tarefas específicas.

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

Este exemplo gerencia a seguinte saída.

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

Compilando o código

Copie o código de exemplo e cole-o em um projeto do Visual Studio, ou cole-o em um arquivo chamado scheduler-instance.cpp e execute o comando a seguir em uma janela do Prompt de comando do Visual Studio.

cl.exe /EHsc scheduler-instance.cpp

Confira também

Instâncias de agendador
Como especificar políticas de agendador específicas