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.
Eine einfache Aufgabe ist eine Aufgabe, die Sie direkt von einem Concurrency::Scheduler-Objekt oder einem Concurrency::ScheduleGroup-Objekt planen. Einfache Aufgaben sind nützlich, wenn Sie vorhandenen Code anpassen, um die Planungsfunktionalität der Concurrency Runtime zu verwenden.
Vorbereitungsmaßnahmen
Bevor Sie mit dieser exemplarische Vorgehensweise beginnen, lesen Sie das Thema Taskplaner (Concurrency Runtime).
Beispiel
Beschreibung
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 in einem separaten Thread aufzurufen.
Code
// 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;
}
Kommentare
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-Direktive für die Headerdatei concrt.h hinzu.
#include <concrt.h>
Fügen Sie eine using-Direktive für den Concurrency-Namespace hinzu.
using namespace Concurrency;
Ändern Sie die Deklaration von MyThreadFunction so, dass die __cdecl-Aufrufkonvention verwendet und void zurückgegeben wird.
void __cdecl MyThreadFunction(LPVOID param);
Ändern Sie die MyData-Struktur so, dass ein Concurrency::event-Objekt eingeschlossen wird, das der Hauptanwendung den Abschluss der Aufgabe signalisiert.
typedef struct MyData { int val1; int val2; event signal; } MYDATA, *PMYDATA;
Ersetzen Sie den Aufruf von CreateThread durch einen Aufruf der Concurrency::CurrentScheduler::ScheduleTask-Methode.
CurrentScheduler::ScheduleTask(MyThreadFunction, pData);
Ersetzen Sie den Aufruf von WaitForSingleObject durch einen Aufruf der Concurrency::event::wait-Methode, um auf den Abschluss der Aufgabe zu warten.
// 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 Concurrency::event::set-Methode auf, um der Hauptanwendung den Abschluss der Aufgabe zu signalisieren.
pData->signal.set();
Entfernen Sie die return-Anweisung von MyThreadFunction.
Beispiel
Beschreibung
Im folgenden vollständigen Beispiel wird eine einfache Aufgabe verwendet, um die MyThreadFunction-Funktion aufzurufen.
Code
// 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();
}