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.
A einfache Aufgabe ist eine Aufgabe, die Sie planen, direkt aus einem concurrency::Scheduler oder concurrency::ScheduleGroup Objekt.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 für den concurrency-Namespace eine using-Direktive 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 der MyData Struktur gehören ein concurrency::event -Objekt, das das Hauptfenster der Anwendung signalisiert, dass die Aufgabe beendet hat.
typedef struct MyData { int val1; int val2; event signal; } MYDATA, *PMYDATA;
Ersetzen Sie den Aufruf von CreateThread mit einem Aufruf der Concurrency::CurrentScheduler::ScheduleTask Methode.
CurrentScheduler::ScheduleTask(MyThreadFunction, pData);
Ersetzen Sie den Aufruf von WaitForSingleObject mit einem Aufruf der Concurrency::event::wait -Methode, um zu warten, bis die Aufgabe abgeschlossen.
// 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)
Am Ende der MyThreadFunction Funktion, rufen Sie die Concurrency::event::set -Methode, um für die Hauptanwendung zu signalisieren, dass die Aufgabe beendet hat.
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();
}