演练:调整现有代码以使用轻量级任务

本主题演示如何改编现有代码,从而使用 Windows API 创建并执行一个线程来使用轻量级任务。

轻量级任务是直接根据 Concurrency::SchedulerConcurrency::ScheduleGroup 对象计划的任务。 改编现有代码以使用并发运行时的日程排定功能时,轻量级任务很有用。

系统必备

在开始本演练之前,请阅读任务计划程序(并发运行时)这一主题。

示例

说明

下面的示例阐释了使用 Windows API 创建和执行线程的典型方法。 此示例使用 CreateThread 函数对单独线程调用 MyThreadFunction

代码

// windows-threads.cpp
#include <windows.h>
#include <tchar.h>
#include <strsafe.h>

#define BUF_SIZE 255

DWORD WINAPI MyThreadFunction(LPVOID param);

// Data structure for threads to use.
typedef struct MyData {
    int val1;
    int val2;
} MYDATA, *PMYDATA;

int _tmain()
{
   // Allocate memory for thread data.
   PMYDATA pData = (PMYDATA) HeapAlloc(GetProcessHeap(), 
      HEAP_ZERO_MEMORY, sizeof(MYDATA));

   if( pData == NULL )
   {
      ExitProcess(2);
   }

   // Set the values of the thread data.
   pData->val1 = 50;
   pData->val2 = 100;

   // Create the thread to begin execution on its own.
   DWORD dwThreadId;
   HANDLE hThread = CreateThread( 
      NULL,                   // default security attributes
      0,                      // use default stack size  
      MyThreadFunction,       // thread function name
      pData,                  // argument to thread function 
      0,                      // use default creation flags 
      &dwThreadId);           // returns the thread identifier 

   if (hThread == NULL) 
   {      
      ExitProcess(3);
   }

   // Wait for the thread to finish.
   WaitForSingleObject(hThread, INFINITE);

   // Close the thread handle and free memory allocation.
   CloseHandle(hThread);
   HeapFree(GetProcessHeap(), 0, pData);

   return 0;
}

DWORD WINAPI MyThreadFunction(LPVOID lpParam)
{
   PMYDATA pData = (PMYDATA)lpParam;

   // Use thread-safe functions to print the parameter values.

   TCHAR msgBuf[BUF_SIZE];
   StringCchPrintf(msgBuf, BUF_SIZE, TEXT("Parameters = %d, %d\n"), 
     pData->val1, pData->val2); 

   size_t cchStringSize;
   StringCchLength(msgBuf, BUF_SIZE, &cchStringSize);

   DWORD dwChars;
   WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), msgBuf, (DWORD)cchStringSize, &dwChars, NULL);

   return 0;
}

注释

该示例产生下面的输出。

Parameters = 50, 100

下列步骤演示如何调整代码示例以使用并发运行时执行相同任务。

调整示例以使用轻量级任务

  1. 为头文件 concrt.h 添加一个 #include 指令。

    #include <concrt.h>
    
  2. Concurrency命名空间添加 using 指令。

    using namespace Concurrency;
    
  3. 更改 MyThreadFunction 的声明以使用 __cdecl 调用约定并返回 void。

    void __cdecl MyThreadFunction(LPVOID param);
    
  4. 修改 MyData 结构以包括向任务已完成的主应用程序发送信号的 Concurrency::event 对象。

    typedef struct MyData {
        int val1;
        int val2;
        event signal;
    } MYDATA, *PMYDATA;
    
  5. 不调用 CreateThread,改为调用 Concurrency::CurrentScheduler::ScheduleTask 方法。

    CurrentScheduler::ScheduleTask(MyThreadFunction, pData);
    
  6. 不调用 WaitForSingleObject,改为调用 Concurrency::event::wait 方法以等待任务完成。

    // Wait for the task to finish.
    pData->signal.wait();
    
  7. 移除对 CloseHandle 的调用。

  8. 更改 MyThreadFunction 定义的签名以与步骤 3 匹配。

    void __cdecl MyThreadFunction(LPVOID lpParam)
    
  9. MyThreadFunction 函数的末尾,调用 Concurrency::event::set 方法以向任务已完成的主应用程序发送信号。

    pData->signal.set();
    
  10. MyThreadFunction 中移除 return 语句。

示例

说明

下面已完成的示例演示了使用轻量级任务调用 MyThreadFunction 函数的代码。

代码

// migration-lwt.cpp
// compile with: /EHsc
#include <windows.h>
#include <tchar.h>
#include <strsafe.h>
#include <concrt.h>

using namespace Concurrency;

#define BUF_SIZE 255

void __cdecl MyThreadFunction(LPVOID param);

// Data structure for threads to use.
typedef struct MyData {
    int val1;
    int val2;
    event signal;
} MYDATA, *PMYDATA;

int _tmain()
{
   // Allocate memory for thread data.
   PMYDATA pData = (PMYDATA) HeapAlloc(GetProcessHeap(), 
      HEAP_ZERO_MEMORY, sizeof(MYDATA));

   if( pData == NULL )
   {
      ExitProcess(2);
   }

   // Set the values of the thread data.
   pData->val1 = 50;
   pData->val2 = 100;

   // Create the thread to begin execution on its own.
   CurrentScheduler::ScheduleTask(MyThreadFunction, pData);

   // Wait for the task to finish.
   pData->signal.wait();

   // Free memory allocation.
   HeapFree(GetProcessHeap(), 0, pData);

   return 0;
}

void __cdecl MyThreadFunction(LPVOID lpParam)
{
   PMYDATA pData = (PMYDATA)lpParam;

   // Use thread-safe functions to print the parameter values.

   TCHAR msgBuf[BUF_SIZE];
   StringCchPrintf(msgBuf, BUF_SIZE, TEXT("Parameters = %d, %d\n"), 
     pData->val1, pData->val2); 

   size_t cchStringSize;
   StringCchLength(msgBuf, BUF_SIZE, &cchStringSize);

   DWORD dwChars;
   WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), msgBuf, (DWORD)cchStringSize, &dwChars, NULL);

   pData->signal.set();
}

请参见

参考

Scheduler 类

概念

任务计划程序(并发运行时)