Genomgång: Anpassa befintlig kod för att använda lätta uppgifter

Det här avsnittet visar hur du anpassar befintlig kod som använder Windows-API:et för att skapa och köra en tråd för att använda en lätt uppgift.

En lätt uppgift är en uppgift som du schemalägger direkt från en samtidighet::Scheduler eller samtidighet::ScheduleGroup-objekt . Enklare uppgifter är användbara när du anpassar befintlig kod för att använda schemaläggningsfunktionerna i Concurrency Runtime.

Förutsättningar

Innan du påbörjar den här genomgången läser du ämnet Schemaläggare.

Exempel

I följande exempel visas typisk användning av Windows-API:et för att skapa och köra en tråd. I det här exemplet används funktionen CreateThread för att anropa MyThreadFunction i en separat tråd.

Inledande 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;
}

Det här exemplet genererar följande utdata.

Parameters = 50, 100

Följande steg visar hur du anpassar kodexemplet för att använda Concurrency Runtime för att utföra samma uppgift.

Så här anpassar du exemplet för att använda en lättviktig uppgift

  1. Lägg till ett #include direktiv för huvudfilen concrt.h.
#include <concrt.h>
  1. Lägg till ett using direktiv för concurrency namnområdet.
using namespace concurrency;
  1. Ändra deklarationen för MyThreadFunction att använda anropskonventionen __cdecl och returnera void.
void __cdecl MyThreadFunction(LPVOID param);
  1. MyData Ändra strukturen så att den innehåller ett samtidighetsobjekt::händelseobjekt som signalerar till huvudprogrammet att aktiviteten har slutförts.
typedef struct MyData {
    int val1;
    int val2;
    event signal;
} MYDATA, *PMYDATA;
  1. Ersätt anropet till CreateThread med ett anrop till metoden concurrency::CurrentScheduler::ScheduleTask .
CurrentScheduler::ScheduleTask(MyThreadFunction, pData);
  1. Ersätt anropet till WaitForSingleObject med ett anrop till metoden concurrency::event::wait för att vänta tills aktiviteten har slutförts.
// Wait for the task to finish.
pData->signal.wait();
  1. Ta bort anropet till CloseHandle.

  2. Ändra signaturen för definitionen för MyThreadFunction så att den matchar steg 3.

void __cdecl MyThreadFunction(LPVOID lpParam)
  1. I slutet av MyThreadFunction funktionen anropar du metoden concurrency::event::set för att signalera till huvudprogrammet att aktiviteten har slutförts.
pData->signal.set();
  1. Ta bort uttalandet return från MyThreadFunction.

Slutförd kod

Följande slutförda exempel visar kod som använder en enkel uppgift för att anropa MyThreadFunction funktionen.

// 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();
}

Se även

Aktivitetsschemaläggare
Scheduler-klass