Instruktaż: Dostosowanie istniejącego kodu w celu użycia lekkie zadań
W tym temacie przedstawiono sposób dostosować istniejący kod, który używa interfejsu API systemu Windows do tworzenia i wykonywania wątku, aby użyć lekkie zadania.
A lekki zadania jest zadaniem, które można zaplanować bezpośrednio z concurrency::Scheduler lub concurrency::ScheduleGroup obiektu.Lekkie zadań są przydatne, gdy dostosowanie istniejącego kodu, aby użyć funkcji planowania Runtime współbieżności.
Wymagania wstępne
Przed rozpoczęciem tego instruktażu, przeczytaj temat Harmonogram zadań (współbieżności Runtime).
Przykład
Opis
Poniższy przykład ilustruje typowym Windows API do tworzenia i wykonywania wątku.W tym przykładzie CreateThread funkcji do wywołania MyThreadFunction w osobnym wątku.
Kod
// 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;
}
Komentarze
Ten przykład generuje następujące wyniki.
Parameters = 50, 100
Poniższe kroki pokazują jak dostosowanie przykład kodu do wykonania tego samego zadania za pomocą Runtime współbieżności.
W przykładzie, aby użyć zadania lekkie dostosowanie
Dodaj #include w dyrektywie dla concrt.h pliku nagłówka.
#include <concrt.h>
Dodaj using w dyrektywie dla concurrency obszaru nazw.
using namespace concurrency;
Zmienianie deklaracji MyThreadFunction , aby użyć __cdecl konwencji wywoływania i przywrócić void.
void __cdecl MyThreadFunction(LPVOID param);
Modyfikowanie MyData strukturę, aby uwzględnić concurrency::event obiektu sygnalizującego główną aplikację, zakończył zadanie.
typedef struct MyData { int val1; int val2; event signal; } MYDATA, *PMYDATA;
Zastąpić wywołanie CreateThread z zaproszeniem do concurrency::CurrentScheduler::ScheduleTask metody.
CurrentScheduler::ScheduleTask(MyThreadFunction, pData);
Zastąpić wywołanie WaitForSingleObject z zaproszeniem do concurrency::event::wait metoda czekać na zakończenie zadania.
// Wait for the task to finish. pData->signal.wait();
Usunąć wywołanie CloseHandle.
Zmienić podpis w definicji MyThreadFunction do kroku 3.
void __cdecl MyThreadFunction(LPVOID lpParam)
Na koniec MyThreadFunction działać, call concurrency::event::set metoda sygnału głównej aplikacji zakończył zadanie.
pData->signal.set();
Usuń return instrukcji od MyThreadFunction.
Przykład
Opis
Następujący przykład pokazuje kod wykorzystujący lekkie zadania do wywołania MyThreadFunction funkcji.
Kod
// 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();
}