Partager via


Procédure pas à pas : adaptation d’un code existant pour l’utilisation de tâches légères

Cette rubrique montre comment adapter le code existant qui utilise l’API Windows pour créer et exécuter un thread pour utiliser une tâche légère.

Une tâche légère est une tâche que vous planifiez directement à partir d’un objet concurrency ::Scheduler ou concurrency ::ScheduleGroup. Les tâches légères s’avèrent utiles quand vous adaptez du code existant pour utiliser les fonctionnalités de planification du runtime d’accès concurrentiel.

Prérequis

Avant de commencer cette procédure pas à pas, lisez la rubrique Planificateur de tâches.

Exemple

L’exemple suivant illustre l’utilisation classique de l’API Windows pour créer et exécuter un thread. Cet exemple utilise la fonction CreateThread pour appeler le MyThreadFunction thread distinct.

Code initial

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

Cet exemple produit la sortie suivante.

Parameters = 50, 100

Les étapes suivantes montrent comment adapter l’exemple de code pour utiliser le runtime d’accès concurrentiel pour effectuer la même tâche.

Pour adapter l’exemple pour utiliser une tâche légère

  1. Ajoutez une #include directive pour le fichier d’en-tête concrt.h.
#include <concrt.h>
  1. Ajoutez une using directive pour l’espace concurrency de noms.
using namespace concurrency;
  1. Modifiez la déclaration de l’utilisation de MyThreadFunction la convention d’appel __cdecl et retournez void.
void __cdecl MyThreadFunction(LPVOID param);
  1. Modifiez la MyData structure pour inclure un objet concurrency ::event qui signale à l’application principale que la tâche a terminée.
typedef struct MyData {
    int val1;
    int val2;
    event signal;
} MYDATA, *PMYDATA;
  1. Remplacez l’appel par CreateThread un appel à la méthode concurrency ::CurrentScheduler ::ScheduleTask .
CurrentScheduler::ScheduleTask(MyThreadFunction, pData);
  1. Remplacez l’appel par WaitForSingleObject un appel à la méthode concurrency ::event ::wait pour attendre la fin de la tâche.
// Wait for the task to finish.
pData->signal.wait();
  1. Supprimez l’appel à CloseHandle.

  2. Modifiez la signature de la définition de MyThreadFunction l’étape 3.

void __cdecl MyThreadFunction(LPVOID lpParam)
  1. À la fin de la MyThreadFunction fonction, appelez la méthode concurrency ::event ::set pour signaler à l’application principale que la tâche a terminée.
pData->signal.set();
  1. Supprimez l’instruction return de MyThreadFunction.

Code terminé

L’exemple terminé suivant montre le code qui utilise une tâche légère pour appeler la MyThreadFunction fonction.

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

Voir aussi

Planificateur de tâches
Scheduler, classe