Exemplarische Vorgehensweise: Anpassen von vorhandenem Code für die Verwendung einfacher Aufgaben
In diesem Thema wird erläutert, wie vorhandener Code, der die Windows-API verwendet, zum Erstellen und Ausführen eines Threads für die Ausführung einer einfachen Aufgabe angepasst wird.
Ein einfacher Vorgang ist ein Vorgang , den Sie direkt aus einem Parallelitätsobjekt::Scheduler oder Parallelität::ScheduleGroup-Objekt planen. Einfache Aufgaben sind nützlich, wenn Sie vorhandenen Code anpassen, um die Planungsfunktionalität der Concurrency Runtime zu verwenden.
Voraussetzungen
Bevor Sie mit dieser exemplarischen Vorgehensweise beginnen, lesen Sie das Thema "Vorgangsplaner".
Beispiel
Das folgende Beispiel veranschaulicht die typische Verwendung der Windows-API zum Erstellen und Ausführen eines Threads. In diesem Beispiel wird die CreateThread-Funktion verwendet, um die MyThreadFunction
Funktion in einem separaten Thread aufzurufen.
Anfangscode
// 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;
}
Folgende Ergebnisse werden zurückgegeben:
Parameters = 50, 100
Die folgenden Schritte geben an, wie das Codebeispiel angepasst wird, um die Concurrency Runtime zum Durchführen der gleichen Aufgabe zu verwenden.
So passen Sie das Beispiel an, um eine einfache Aufgabe zu verwenden
- Fügen Sie eine
#include
-Anweisung für die Headerdatei concrt.h hinzu.
#include <concrt.h>
- Fügen Sie eine
using
-Direktive für denconcurrency
-Namespace hinzu.
using namespace concurrency;
- Ändern Sie die Deklaration von
MyThreadFunction
so, dass die__cdecl
-Aufrufkonvention verwendet undvoid
zurückgegeben wird.
void __cdecl MyThreadFunction(LPVOID param);
- Ändern Sie die
MyData
Struktur so, dass sie ein Parallelitätsobjekt::event enthält, das der Standard Anwendung signalisiert, die die Aufgabe abgeschlossen hat.
typedef struct MyData {
int val1;
int val2;
event signal;
} MYDATA, *PMYDATA;
- Ersetzen Sie den Aufruf durch einen Aufruf
CreateThread
der Parallelität::CurrentScheduler::ScheduleTask-Methode .
CurrentScheduler::ScheduleTask(MyThreadFunction, pData);
- Ersetzen Sie den Aufruf durch einen Aufruf
WaitForSingleObject
der Parallelität::event::wait-Methode , um zu warten, bis die Aufgabe abgeschlossen ist.
// Wait for the task to finish.
pData->signal.wait();
Entfernen Sie den Aufruf von
CloseHandle
.Ändern Sie die Signatur der Definition von
MyThreadFunction
so, dass sie Schritt 3 entspricht.
void __cdecl MyThreadFunction(LPVOID lpParam)
- Rufen Sie am Ende der
MyThreadFunction
Funktion die Parallelität::event::set-Methode auf, um der Standard Anwendung zu signalisieren, dass die Aufgabe abgeschlossen ist.
pData->signal.set();
- Entfernen Sie die
return
-Anweisung vonMyThreadFunction
.
Abgeschlossener Code
Im folgenden vollständigen Beispiel wird eine einfache Aufgabe verwendet, um die MyThreadFunction
-Funktion aufzurufen.
// 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();
}