Menerima Pemberitahuan Peristiwa Asinkron

Pemberitahuan peristiwa asinkron adalah teknik yang memungkinkan aplikasi untuk terus memantau peristiwa tanpa memonopoli sumber daya sistem. Pemberitahuan peristiwa asinkron memiliki batasan keamanan yang sama dengan panggilan asinkron lainnya. Anda dapat melakukan panggilan semisinkron sebagai gantinya. Untuk informasi selengkapnya, lihat Memanggil Metode.

Antrean peristiwa asinkron yang dirutekan ke klien berpotensi tumbuh sangat besar. Oleh karena itu, WMI menerapkan kebijakan di seluruh sistem untuk menghindari kehabisan memori. WMI memperlambat peristiwa, atau mulai menghilangkan peristiwa dari antrean ketika antrean tumbuh melewati ukuran tertentu.

WMI menggunakan properti LowThresholdOnEvents dan HighThresholdOnEvents dari kelas Win32_WMISetting untuk menetapkan batasan penghindarian di luar memori. Nilai minimum menunjukkan kapan WMI harus mulai memperlambat pemberitahuan peristiwa, dan nilai maksimum menunjukkan kapan harus mulai menghilangkan peristiwa. Nilai default untuk ambang batas rendah dan tinggi adalah 1000000 (10 MB) dan 2000000 (20 MB). Selain itu, Anda dapat mengatur properti MaxWaitOnEvents untuk menjelaskan jumlah waktu WMI harus menunggu sebelum menghilangkan peristiwa. Nilai default untuk MaxWaitOnEvents adalah 2000, atau 2 detik.

Menerima Pemberitahuan Peristiwa Asinkron di VBScript

Panggilan pembuatan skrip untuk menerima pemberitahuan peristiwa pada dasarnya sama dengan semua panggilan asinkron dengan masalah keamanan yang sama. Untuk informasi selengkapnya, lihat Melakukan Panggilan Asinkron dengan VBScript.

Untuk menerima pemberitahuan peristiwa asinkron di VBScript

  1. Buat objek sink dengan memanggil WScript.CreateObject dan tentukan progid "WbemScripting" dan jenis objek SWbemSink. Objek sink menerima pemberitahuan.

  2. Tulis sub-rutin untuk setiap peristiwa yang ingin Anda tangani. Tabel berikut mencantumkan peristiwa SWbemSink .

    Kejadian Makna
    OnObjectReady Melaporkan pengembalian objek ke sink. Menggunakan panggilan ini mengembalikan satu objek setiap kali sampai operasi selesai.
    OnCompleted Melaporkan ketika panggilan asinkron selesai. Kejadian ini tidak pernah terjadi jika operasi tidak terbatas.
    OnObjectPut Melaporkan penyelesaian operasi put asinkron. Kejadian ini mengembalikan jalur objek instans atau kelas yang disimpan.
    OnProgress Melaporkan status panggilan asinkron yang sedang berlangsung. Tidak semua penyedia mendukung laporan kemajuan sementara.
    Batalkan Membatalkan semua operasi asinkron yang luar biasa yang terkait dengan sink objek ini.

     

Contoh kode VBScript berikut memberi tahu penghapusan proses dengan interval polling 10 detik. Dalam skrip ini, subroutine SINK_OnObjectReady menangani kejadian peristiwa. Dalam contoh, objek sink diberi nama "Sink", namun Anda dapat memberi nama objek ini seperti yang Anda pilih.

strComputer = "." 
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2") 
Set MySink = WScript.CreateObject( _
    "WbemScripting.SWbemSink","SINK_")

objWMIservice.ExecNotificationQueryAsync MySink, _
    "SELECT * FROM __InstanceDeletionEvent" _
    & " WITHIN 10 WHERE TargetInstance ISA 'Win32_Process'"


WScript.Echo "Waiting for events..."

While (True)
    Wscript.Sleep(1000)
Wend

Sub SINK_OnObjectReady(objObject, objAsyncContext)
    Wscript.Echo "__InstanceDeletionEvent event has occurred."
End Sub

Sub SINK_OnCompleted(objObject, objAsyncContext)
    WScript.Echo "Event call complete."
End Sub

Menerima Pemberitahuan Peristiwa Asinkron di C++

Untuk melakukan pemberitahuan asinkron, Anda membuat utas terpisah semata-mata untuk memantau dan menerima peristiwa dari Windows Management Instrumentation (WMI). Ketika utas tersebut menerima pesan, utas akan memberi tahu aplikasi utama Anda.

Dengan mendedikasikan utas terpisah, Anda mengizinkan proses utama Anda untuk melakukan aktivitas lain sambil menunggu peristiwa tiba. Pengiriman pemberitahuan asinkron meningkatkan performa tetapi mungkin memberikan keamanan yang lebih sedikit daripada yang Anda inginkan. Di C++, Anda memiliki opsi untuk menggunakan antarmuka IWbemUnsecuredApartment atau melakukan pemeriksaan akses pada deskriptor keamanan. Untuk informasi selengkapnya, lihat Mengatur Keamanan pada Panggilan Asinkron.

Untuk menyiapkan pemberitahuan peristiwa asinkron

  1. Sebelum menginisialisasi pemberitahuan asinkron apa pun, pastikan parameter penghindaran di luar memori Anda diatur dengan benar di Win32_WMISetting.

  2. Tentukan jenis peristiwa apa yang ingin Anda terima.

    WMI mendukung peristiwa intrinsik dan ekstrinsik. Peristiwa intrinsik adalah peristiwa yang telah ditentukan sebelumnya oleh WMI, sedangkan peristiwa ekstrinsik adalah peristiwa yang ditentukan oleh penyedia pihak ketiga. Untuk informasi selengkapnya, lihat Menentukan Jenis Peristiwa yang Akan Diterima.

Prosedur berikut menjelaskan cara menerima pemberitahuan peristiwa asinkron di C++.

Untuk menerima pemberitahuan peristiwa asinkron di C++

  1. Siapkan aplikasi Anda dengan panggilan ke fungsi CoInitializeEx dan CoInitializeSecurity .

    Memanggil CoInitializeEx menginisialisasi COM, sementara CoInitializeSecurity memberikan izin kepada WMI untuk memanggil proses konsumen. Fungsi CoInitializeEx juga memberi Anda kemampuan untuk memprogram aplikasi multithreaded, yang diperlukan untuk pemberitahuan asinkron. Untuk informasi selengkapnya, lihat Menjaga Keamanan WMI.

    Kode dalam topik ini memerlukan referensi berikut dan pernyataan #include untuk dikompilasi dengan benar.

    #define _WIN32_DCOM
    #include <iostream>
    using namespace std;
    #include <wbemidl.h>
    

    Contoh kode berikut menjelaskan cara menyiapkan konsumen peristiwa sementara dengan panggilan ke CoInitializeEx dan CoInitializeSecurity.

    void main(int argc, char **argv)
    {
        HRESULT hr = 0;
        hr = CoInitializeEx (0, COINIT_MULTITHREADED);
        hr = CoInitializeSecurity (NULL, 
           -1, 
           NULL, 
           NULL,   
           RPC_C_AUTHN_LEVEL_NONE, 
           RPC_C_IMP_LEVEL_IMPERSONATE, 
           NULL,
           EOAC_NONE,
           NULL); 
    
        if (FAILED(hr))
        {
           CoUninitialize();
           cout << "Failed to initialize security. Error code = 0x"
               << hex << hr << endl;
           return;
        }
    
    // ...
    }
    
  2. Buat objek sink melalui antarmuka IWbemObjectSink .

    WMI menggunakan IWbemObjectSink untuk mengirim pemberitahuan peristiwa dan melaporkan status pada operasi asinkron atau pemberitahuan peristiwa.

  3. Daftarkan konsumen peristiwa Anda dengan panggilan ke metode IWbemServices::ExecNotificationQueryAsync .

    Pastikan parameter pResponseHandler menunjuk ke objek sink yang dibuat pada langkah sebelumnya.

    Tujuan pendaftaran hanya untuk menerima pemberitahuan yang diperlukan. Menerima pemberitahuan yang berlebihan membuang-buang waktu pemrosesan dan pengiriman; dan tidak menggunakan kemampuan pemfilteran WMI dengan potensi maksimal.

    Namun, konsumen sementara dapat menerima lebih dari satu jenis peristiwa. Dalam hal ini, konsumen sementara harus melakukan panggilan terpisah ke IWbemServices::ExecNotificationQueryAsync untuk setiap jenis peristiwa. Misalnya, konsumen mungkin memerlukan pemberitahuan saat proses baru dibuat (peristiwa pembuatan instans atau __InstanceCreationEvent) dan untuk perubahan pada kunci registri tertentu (peristiwa registri seperti RegistryKeyChangeEvent). Oleh karena itu, konsumen melakukan satu panggilan ke ExecNotificationQueryAsync untuk mendaftar peristiwa pembuatan instans dan panggilan lain ke ExecNotificationQueryAsync untuk mendaftar untuk peristiwa registri.

    Jika Anda memilih untuk membuat konsumen peristiwa yang mendaftar untuk beberapa peristiwa, Anda harus menghindari mendaftarkan beberapa kelas dengan sink yang sama. Sebagai gantinya, gunakan sink terpisah untuk setiap kelas peristiwa terdaftar. Memiliki sink khusus menyederhanakan pemrosesan dan bantuan dalam pemeliharaan, memungkinkan Anda membatalkan satu pendaftaran tanpa memengaruhi yang lain.

  4. Lakukan aktivitas yang diperlukan di konsumen peristiwa Anda.

    Langkah ini harus berisi sebagian besar kode Anda dan menyertakan aktivitas seperti menampilkan peristiwa ke antarmuka pengguna.

  5. Setelah selesai, batalkan pendaftaran konsumen peristiwa sementara dengan panggilan ke peristiwa IWbemServices::CancelAsyncCall .

    Terlepas dari apakah panggilan ke CancelAsyncCall berhasil atau gagal, jangan hapus objek sink hingga jumlah referensi objek mencapai nol. Untuk informasi selengkapnya, lihat Memanggil Metode.