Panduan: Mengadaptasi Kode yang Ada untuk Menggunakan Tugas Ringan

Topik ini menunjukkan cara mengadaptasi kode yang ada yang menggunakan WINDOWS API untuk membuat dan menjalankan utas untuk menggunakan tugas yang ringan.

Tugas ringan adalah tugas yang Anda jadwalkan langsung dari objek konkurensi::Scheduler atau konkurensi::ScheduleGroup. Tugas ringan berguna saat Anda mengadaptasi kode yang ada untuk menggunakan fungsionalitas penjadwalan Concurrency Runtime.

Prasyarat

Sebelum Anda memulai panduan ini, baca topik Penjadwal Tugas.

Contoh

Contoh berikut mengilustrasikan penggunaan umum API Windows untuk membuat dan menjalankan utas. Contoh ini menggunakan fungsi CreateThread untuk memanggil MyThreadFunction pada utas terpisah.

Kode awal

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

Contoh ini menghasilkan output berikut.

Parameters = 50, 100

Langkah-langkah berikut menunjukkan cara mengadaptasi contoh kode untuk menggunakan Runtime Konkurensi untuk melakukan tugas yang sama.

Untuk mengadaptasi contoh untuk menggunakan tugas ringan

  1. Tambahkan direktif #include untuk file header concrt.h.
#include <concrt.h>
  1. Tambahkan direktif using untuk concurrency namespace layanan.
using namespace concurrency;
  1. Ubah deklarasi MyThreadFunction untuk menggunakan __cdecl konvensi panggilan dan untuk mengembalikan void.
void __cdecl MyThreadFunction(LPVOID param);
  1. MyData Ubah struktur untuk menyertakan konkurensi::objek peristiwa yang memberi sinyal ke aplikasi utama bahwa tugas telah selesai.
typedef struct MyData {
    int val1;
    int val2;
    event signal;
} MYDATA, *PMYDATA;
  1. Ganti panggilan ke CreateThread dengan panggilan ke metode konkurensi::CurrentScheduler::ScheduleTask .
CurrentScheduler::ScheduleTask(MyThreadFunction, pData);
  1. Ganti panggilan ke WaitForSingleObject dengan panggilan ke konkurensi::event::wait method untuk menunggu tugas selesai.
// Wait for the task to finish.
pData->signal.wait();
  1. Hapus panggilan ke CloseHandle.

  2. Ubah tanda tangan definisi MyThreadFunction agar sesuai dengan langkah 3.

void __cdecl MyThreadFunction(LPVOID lpParam)
  1. Di akhir MyThreadFunction fungsi, panggil metode konkurensi::event::set untuk memberi sinyal ke aplikasi utama bahwa tugas telah selesai.
pData->signal.set();
  1. return Hapus pernyataan dari MyThreadFunction.

Kode yang telah selesai

Contoh lengkap berikut menunjukkan kode yang menggunakan tugas ringan untuk memanggil MyThreadFunction fungsi.

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

Baca juga

Tugas Microsoft Azure Scheduler
Kelas Penjadwal