演练:调整现有代码以使用轻量级任务
本主题演示如何改编现有代码,从而使用 Windows API 创建并执行一个线程来使用轻量级任务。
轻量级任务是直接根据 Concurrency::Scheduler 或 Concurrency::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
下列步骤演示如何调整代码示例以使用并发运行时执行相同任务。
调整示例以使用轻量级任务
为头文件 concrt.h 添加一个 #include 指令。
#include <concrt.h>
为Concurrency命名空间添加 using 指令。
using namespace Concurrency;
更改 MyThreadFunction 的声明以使用 __cdecl 调用约定并返回 void。
void __cdecl MyThreadFunction(LPVOID param);
修改 MyData 结构以包括向任务已完成的主应用程序发送信号的 Concurrency::event 对象。
typedef struct MyData { int val1; int val2; event signal; } MYDATA, *PMYDATA;
不调用 CreateThread,改为调用 Concurrency::CurrentScheduler::ScheduleTask 方法。
CurrentScheduler::ScheduleTask(MyThreadFunction, pData);
不调用 WaitForSingleObject,改为调用 Concurrency::event::wait 方法以等待任务完成。
// Wait for the task to finish. pData->signal.wait();
移除对 CloseHandle 的调用。
更改 MyThreadFunction 定义的签名以与步骤 3 匹配。
void __cdecl MyThreadFunction(LPVOID lpParam)
在 MyThreadFunction 函数的末尾,调用 Concurrency::event::set 方法以向任务已完成的主应用程序发送信号。
pData->signal.set();
从 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();
}