Menggunakan Antrean Kerja

Topik ini menjelaskan cara menggunakan antrean kerja di Microsoft Media Foundation.

Menggunakan Antrean Kerja

Antrean kerja adalah cara yang efisien untuk melakukan operasi asinkron pada utas lain. Secara konseptual, Anda menempatkan item kerja dalam antrean, dan antrean memiliki utas yang menarik setiap item dari antrean dan mengirimkannya. Item kerja diimplementasikan sebagai panggilan balik dengan menggunakan antarmuka IMFAsyncCallback .

Media Foundation membuat beberapa antrean kerja standar, yang disebut antrean kerja platform. Aplikasi juga dapat membuat antrean kerja mereka sendiri, yang disebut antrean kerja privat. Untuk daftar antrean kerja platform, lihat Pengidentifikasi Antrean Kerja. Untuk membuat antrean kerja privat, panggil MFAllocateWorkQueue. Fungsi ini mengembalikan pengidentifikasi untuk antrean kerja baru. Untuk meletakkan item dalam antrean, panggil MFPutWorkItem atau MFPutWorkItemEx. Dalam kedua kasus, Anda harus menentukan antarmuka panggilan balik.

  • MFPutWorkItem mengambil pointer ke antarmuka IMFAsyncCallback , ditambah objek status opsional yang mengimplementasikan IUnknown. Ini adalah parameter yang sama yang digunakan dalam metode asinkron, seperti yang dijelaskan dalam topik Metode Panggilan Balik Asinkron. Secara internal, fungsi ini membuat objek hasil asinkron, yang diteruskan ke metode Panggil panggilan balik.
  • MFPutWorkItemEx membawa pointer ke antarmuka IMFAsyncResult . Antarmuka ini mewakili objek hasil asinkron. Buat objek ini dengan memanggil MFCreateAsyncResult dan tentukan antarmuka panggilan balik Anda dan, secara opsional, objek status.

Dalam kedua kasus, utas antrean kerja memanggil metode IMFAsyncCallback::Invoke Anda. Gunakan metode Panggil untuk melakukan item kerja.

Jika lebih dari satu utas atau komponen berbagi antrean kerja yang sama, Anda dapat memanggil MFLockWorkQueue untuk mengunci antrean kerja, yang mencegah platform merilisnya. Untuk setiap panggilan ke MFAllocateWorkQueue atau MFLockWorkQueue, Anda harus memanggil MFUnlockWorkQueue sekali untuk merilis antrean kerja. Misalnya, jika Anda membuat antrean kerja baru lalu menguncinya sekali, Anda harus memanggil MFUnlockWorkQueue dua kali, sekali untuk panggilan ke MFAllocateWorkQueue dan sekali untuk panggilan ke MFLockWorkQueue.

Kode berikut menunjukkan cara membuat antrean kerja baru, meletakkan item kerja dalam antrean, dan merilis antrean kerja.

Lihat Antrean Kerja dan Peningkatan Utas untuk informasi tambahan tentang antrean kerja di Windows 8.

DWORD idWorkQueue = 0;
HRESULT hr = S_OK;

// Create a new work queue.
hr = MFAllocateWorkQueue(&idWorkQueue);

// Put an item on the queue.
if (SUCCEEDED(hr))
{
    hr = MFPutWorkItem(idWorkQueue, pCallback, NULL);
}

// Wait for the callback to be invoked.
if (SUCCEEDED(hr))
{
    WaitForSingleObject(hEvent, INFINITE);
}

// Release the work queue.
if (SUCCEEDED(hr))
{
    hr = MFUnlockWorkQueue(idWorkQueue);
}

Contoh ini mengasumsikan bahwa pCallback adalah penunjuk ke antarmuka IMFAsyncCallback aplikasi. Ini juga mengasumsikan bahwa panggilan balik mengatur handel peristiwa hEvent . Kode menunggu peristiwa ini diatur sebelum memanggil MFUnlockWorkQueue.

Utas antrean kerja selalu dibuat dalam proses pemanggil. Dalam setiap antrean kerja, panggilan balik diserialisasikan. Jika Anda memanggil MFPutWorkItem dua kali dengan antrean kerja yang sama, panggilan balik kedua tidak dipanggil sampai panggilan balik pertama telah kembali.

Mematikan Antrean Kerja

Sebelum memanggil MFShutdown, rilis sumber daya apa pun yang sedang digunakan oleh utas antrean kerja. Untuk menyinkronkan proses ini, Anda dapat mengunci platform Media Foundation, yang mencegah fungsi MFShutdown menutup utas antrean kerja apa pun. Jika MFShutdown dipanggil saat platform dikunci, MFShutdown menunggu beberapa ratus milidetik agar platform tidak terkunci. Jika tidak dibuka dalam waktu tersebut, MFShutdown menutup utas antrean kerja.

Implementasi default IMFAsyncResult secara otomatis mengunci platform Media Foundation saat objek hasil dibuat. Merilis antarmuka membuka kunci platform. Oleh karena itu, Anda hampir tidak perlu mengunci platform secara langsung. Tetapi jika Anda menulis implementasi kustom IMFAsyncResult Anda sendiri, maka Anda harus mengunci dan membuka kunci platform secara manual. Untuk mengunci platform, panggil MFLockPlatform. Untuk membuka kunci platform, panggil MFUnlockPlatform. Misalnya, lihat Objek Hasil Asinkron Kustom.

Setelah Anda memanggil MFShutdown, Anda perlu memastikan bahwa platform tidak terkunci dalam periode waktu habis 5 detik. Lakukan ini dengan merilis semua pointer IMFAsyncResult , dan dengan memanggil MFUnlockPlatform jika Anda mengunci platform secara manual. Pastikan untuk merilis sumber daya apa pun yang digunakan oleh utas antrean kerja, atau aplikasi Anda mungkin membocorkan memori.

Biasanya, jika aplikasi Anda dimatikan dan melepaskan setiap objek Media Foundation sebelum memanggil MFShutdown, Anda tidak perlu khawatir tentang penguncian. Mekanisme penguncian hanya memungkinkan utas antrean kerja keluar dengan lancar setelah Anda memanggil MFShutdown.

Menggunakan Item Kerja Terjadwal

Anda dapat menjadwalkan panggilan balik terjadi setelah jangka waktu yang ditetapkan dengan memanggil MFScheduleWorkItem atau MFScheduleWorkItemEx.

  • MFScheduleWorkItem mengambil penunjuk ke panggilan balik Anda, objek status opsional, dan interval waktu habis.
  • MFScheduleWorkItemEx mengambil pointer ke objek hasil asinkron dan nilai waktu habis.

Tentukan batas waktu sebagai nilai negatif dalam milidetik. Misalnya, untuk menjadwalkan panggilan balik yang akan dipanggil dalam 5 detik, gunakan nilai −5000. Kedua fungsi mengembalikan nilai MFWORKITEM_KEY , yang dapat Anda gunakan untuk membatalkan panggilan balik dengan meneruskannya ke fungsi MFCancelWorkItem .

Item kerja terjadwal selalu menggunakan antrean kerja platform MFASYNC_CALLBACK_QUEUE_TIMER.

Menggunakan Panggilan Balik Berkala

Fungsi MFAddPeriodicCallback menjadwalkan panggilan balik untuk dipanggil secara berkala hingga Anda membatalkannya. Interval panggilan balik diperbaiki; aplikasi tidak dapat mengubahnya. Untuk mengetahui interval yang tepat, panggil MFGetTimerPeriodicity. Interval berada pada urutan 10 milidetik, sehingga fungsi ini dimaksudkan untuk situasi di mana Anda sering membutuhkan "tick," seperti menerapkan jam presentasi. Jika Anda ingin menjadwalkan operasi agar lebih jarang terjadi, gunakan item kerja terjadwal, seperti yang dijelaskan sebelumnya.

Tidak seperti panggilan balik lain yang dijelaskan dalam topik ini, panggilan balik berkala tidak menggunakan antarmuka IMFAsyncCallback . Sebaliknya, ia menggunakan penunjuk fungsi. Untuk informasi selengkapnya, lihat MFPERIODICCALLBACK Callback.

Untuk membatalkan panggilan balik berkala, panggil MFRemovePeriodicCallback.

Panggilan balik berkala menggunakan antrean kerja platform MFASYNC_CALLBACK_QUEUE_TIMER.

Antrean Kerja

MFASYNCRESULT

Peningkatan Antrean kerja dan Utas