如何:管理计划程序实例

计划程序实例允许将特定计划策略与各种工作负荷相关联。 本主题包含两个基本示例,演示如何创建和管理计划程序实例。

这些示例创建使用默认计划程序策略的计划程序。 有关创建使用自定义策略的计划程序的示例,请参阅如何:指定特定计划程序策略

在应用程序中管理计划程序实例

  1. 创建一个 concurrency::SchedulerPolicy 对象,该对象包含要使用的计划程序的策略值。

  2. 调用 concurrency::CurrentScheduler::Create 方法或 concurrency::Scheduler::Create 方法以创建计划程序实例。

    如果使用方法 Scheduler::Create,则需要将计划程序与当前上下文相关联时调用 concurrency::Scheduler::Attach 方法。

  3. 调用 CreateEvent 函数以创建非信号自动重置事件对象的句柄。

  4. 将刚刚创建的事件对象的句柄传递给 concurrency::CurrentScheduler::RegisterShutdownEvent 方法或 concurrency::Scheduler::RegisterShutdownEvent 方法。 这会注册在计划程序被销毁时要设置的事件。

  5. 执行希望当前计划程序计划的任务。

  6. 调用 concurrency::CurrentScheduler::Detach 方法分离当前计划程序,并将以前的计划程序还原为当前计划程序。

    如果使用方法 Scheduler::Create ,请调用 concurrency::Scheduler::Release 方法以递减对象 Scheduler 的引用计数。

  7. 将事件的句柄传递给 WaitForSingleObject 函数,等待计划程序关闭。

  8. 调用 CloseHandle 函数以关闭事件对象的句柄。

示例

以下代码演示了两种管理计划程序实例的方法。 每个示例首先使用默认计划程序来执行输出当前计划程序的唯一标识符的任务。 然后,每个示例使用计划程序实例再次执行同一任务。 最后,每个示例将默认计划程序还原为当前计划程序,并再执行一次任务。

第一个示例使用 concurrency::CurrentScheduler 类创建计划程序实例并将其与当前上下文相关联。 第二个示例使用 concurrency::Scheduler 类执行相同的任务。 通常,CurrentScheduler 类用于处理当前计划程序。 第二个使用 Scheduler 类的示例可用于控制计划程序何时与当前上下文关联,或者希望将特定计划程序与特定任务相关联。

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

本示例生成以下输出。

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

编译代码

复制示例代码,并将它粘贴到 Visual Studio 项目中,或粘贴到名为 scheduler-instance.cpp 的文件中,再在 Visual Studio 命令提示符窗口中运行以下命令。

cl.exe /EHsc scheduler-instance.cpp

另请参阅

计划程序实例
如何:指定特定的计划程序策略