Procedura dettagliata: Adattamento del codice esistente per l'uso di attività leggere
Questo argomento illustra come adattare il codice esistente che usa l'API di Windows per creare ed eseguire un thread per usare un'attività leggera.
Un'attività leggera è un'attività pianificata direttamente da un oggetto concurrency::Scheduler o concurrency::ScheduleGroup . Le attività leggere sono utili quando si adatta il codice esistente per usare la funzionalità di pianificazione del runtime di concorrenza.
Prerequisiti
Prima di iniziare questa procedura dettagliata, leggere l'argomento Utilità di pianificazione.
Esempio
L'esempio seguente illustra l'utilizzo tipico dell'API Windows per creare ed eseguire un thread. In questo esempio viene utilizzata la funzione CreateThread per chiamare su MyThreadFunction
un thread separato.
Codice iniziale
// 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;
}
Questo esempio produce il seguente output:
Parameters = 50, 100
I passaggi seguenti illustrano come adattare l'esempio di codice per usare il runtime di concorrenza per eseguire la stessa attività.
Per adattare l'esempio all'uso di un'attività leggera
- Aggiungere una
#include
direttiva per il file di intestazione concrt.h.
#include <concrt.h>
- Aggiungere una
using
direttiva per lo spazio deiconcurrency
nomi .
using namespace concurrency;
- Modificare la dichiarazione di per usare la
__cdecl
convenzione diMyThreadFunction
chiamata e restituirevoid
.
void __cdecl MyThreadFunction(LPVOID param);
- Modificare la
MyData
struttura in modo da includere un oggetto concurrency::event che segnala all'applicazione principale che l'attività è stata completata.
typedef struct MyData {
int val1;
int val2;
event signal;
} MYDATA, *PMYDATA;
- Sostituire la chiamata a
CreateThread
con una chiamata al metodo concurrency::CurrentScheduler::ScheduleTask .
CurrentScheduler::ScheduleTask(MyThreadFunction, pData);
- Sostituire la chiamata a
WaitForSingleObject
con una chiamata al metodo concurrency::event::wait per attendere il completamento dell'attività.
// Wait for the task to finish.
pData->signal.wait();
Rimuovere la chiamata a
CloseHandle
.Modificare la firma della definizione di
MyThreadFunction
in modo che corrisponda al passaggio 3.
void __cdecl MyThreadFunction(LPVOID lpParam)
- Alla fine della
MyThreadFunction
funzione chiamare il metodo concurrency::event::set per segnalare all'applicazione principale che l'attività è stata completata.
pData->signal.set();
- Rimuovere l'istruzione
return
daMyThreadFunction
.
Codice completato
L'esempio seguente illustra il codice che usa un'attività leggera per chiamare la MyThreadFunction
funzione.
// 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();
}