Partager via


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

Cette rubrique indique comment adapter du code existant qui utilise l'API Windows pour créer et exécuter un thread de façon à utiliser une tâche légère.

A tâche léger est une tâche que vous planifiez directement à partir d'un concurrency::Scheduler ou concurrency::ScheduleGroup objet.Les tâches légères sont utiles lorsque vous adaptez du code existant de façon à utiliser les fonctionnalités de planification du runtime d'accès concurrentiel.

Composants requis

Avant de démarrer cette procédure pas à pas, lisez la rubrique Planificateur de tâches (runtime d'accès concurrentiel).

Exemple

Ee624185.collapse_all(fr-fr,VS.110).gifDescription

L'exemple suivant illustre une utilisation typique de l'API Windows pour créer et exécuter un thread.Cet exemple utilise la fonction CreateThread pour appeler MyThreadFunction sur un thread séparé.

Ee624185.collapse_all(fr-fr,VS.110).gifCode

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

Ee624185.collapse_all(fr-fr,VS.110).gifCommentaires

Cet exemple génère la sortie suivante.

Parameters = 50, 100

Les étapes suivantes indiquent comment adapter l'exemple de code de façon à utiliser le runtime d'accès concurrentiel pour effectuer la même tâche.

Pour adapter l'exemple de façon à utiliser une tâche légère

  1. Ajoutez une directive #include pour le fichier d'en-tête concrt.h.

    #include <concrt.h>
    
  2. Ajoutez une directive using pour l'espace de noms concurrency.

    using namespace concurrency;
    
  3. Modifiez la déclaration de MyThreadFunction de façon à utiliser la convention d'appel __cdecl et à retourner void.

    void __cdecl MyThreadFunction(LPVOID param);
    
  4. Modifier la MyData structure pour inclure un concurrency::event objet qui signale à l'application principale que la tâche est terminée.

    typedef struct MyData {
        int val1;
        int val2;
        event signal;
    } MYDATA, *PMYDATA;
    
  5. Remplacez l'appel à CreateThread avec un appel à la concurrency::CurrentScheduler::ScheduleTask méthode.

    CurrentScheduler::ScheduleTask(MyThreadFunction, pData);
    
  6. Remplacez l'appel à WaitForSingleObject avec un appel à la concurrency::event::wait méthode pour attendre la fin de la tâche.

    // Wait for the task to finish.
    pData->signal.wait();
    
  7. Supprimez l'appel à CloseHandle.

  8. Modifiez la signature de la définition de MyThreadFunction de sorte qu'elle corresponde à l'étape 3.

    void __cdecl MyThreadFunction(LPVOID lpParam)
    
  9. À la fin de la MyThreadFunction de fonction, appelez le concurrency::event::set méthode pour signaler à l'application principale que la tâche est terminée.

    pData->signal.set();
    
  10. Supprimez l'instruction return de MyThreadFunction.

Exemple

Ee624185.collapse_all(fr-fr,VS.110).gifDescription

L'exemple complet suivant montre du code qui utilise une tâche légère pour appeler la fonction MyThreadFunction.

Ee624185.collapse_all(fr-fr,VS.110).gifCode

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

Référence

Scheduler, classe

Concepts

Planificateur de tâches (runtime d'accès concurrentiel)