Condividi tramite


Procedura dettagliata: adattamento del codice esistente per l'utilizzo delle attività leggere

In questo argomento viene illustrato come adattare il codice esistente che utilizza l'API Windows per creare ed eseguire un thread per utilizzare un'attività leggera.

A attività leggero è un'attività che è possibile pianificare direttamente da un concurrency::Scheduler o concurrency::ScheduleGroup oggetto.Le attività leggere sono utili quando si adatta il codice esistente per utilizzare la funzionalità di pianificazione del runtime di concorrenza.

Prerequisiti

Prima di iniziare questa procedura dettagliata, leggere l'argomento Utilità di pianificazione (runtime di concorrenza).

Esempio

Ee624185.collapse_all(it-it,VS.110).gifDescrizione

Nell'esempio seguente viene illustrato l'utilizzo tipico dell'API Windows per creare ed eseguire un thread.In questo esempio viene utilizzata la funzione CreateThread per chiamare MyThreadFunction su un thread separato.

Ee624185.collapse_all(it-it,VS.110).gifCodice

// 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(it-it,VS.110).gifCommenti

Questo esempio produce l'output che segue.

Parameters = 50, 100

Nei passaggi seguenti viene illustrato come adattare l'esempio di codice per l'utilizzo del runtime di concorrenza per eseguire la stessa attività.

Per adattare l'esempio per l'utilizzo di un'attività leggera

  1. Aggiungere una direttiva #include per file di intestazione concrt.h.

    #include <concrt.h>
    
  2. Aggiungere una direttiva using per lo spazio dei nomi concurrency.

    using namespace concurrency;
    
  3. Modificare la dichiarazione di MyThreadFunction in modo da utilizzare la convenzione di chiamata __cdecl e restituire void.

    void __cdecl MyThreadFunction(LPVOID param);
    
  4. Modificare il MyData struttura per includere un concurrency::event oggetto segnala all'applicazione principale che l'attività è terminata.

    typedef struct MyData {
        int val1;
        int val2;
        event signal;
    } MYDATA, *PMYDATA;
    
  5. Sostituire la chiamata a CreateThread con una chiamata di concurrency::CurrentScheduler::ScheduleTask metodo.

    CurrentScheduler::ScheduleTask(MyThreadFunction, pData);
    
  6. Sostituire la chiamata a WaitForSingleObject con una chiamata di concurrency::event::wait metodo per attendere la fine dell'attività.

    // Wait for the task to finish.
    pData->signal.wait();
    
  7. Rimuovere la chiamata a CloseHandle.

  8. Modificare la firma della definizione di MyThreadFunction in modo da corrispondere al passaggio 3.

    void __cdecl MyThreadFunction(LPVOID lpParam)
    
  9. Alla fine del MyThreadFunction funzione, chiamare il concurrency::event::set metodo per segnalare all'applicazione principale che l'attività è terminata.

    pData->signal.set();
    
  10. Rimuovere l'istruzione return da MyThreadFunction.

Esempio

Ee624185.collapse_all(it-it,VS.110).gifDescrizione

Nell'esempio completato seguente viene illustrato il codice che utilizza un'attività leggera per chiamare la funzione MyThreadFunction.

Ee624185.collapse_all(it-it,VS.110).gifCodice

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

Vedere anche

Riferimenti

Classe Scheduler

Concetti

Utilità di pianificazione (runtime di concorrenza)