Bagikan melalui


Menangani dan memicu event

Peristiwa di .NET didasarkan pada model delegasi. Model delegasi mengikuti pola desain pengamat , yang memungkinkan pelanggan untuk mendaftar dan menerima pemberitahuan dari penyedia. Pengirim acara mengirimkan pemberitahuan saat acara terjadi. Penerima peristiwa mendefinisikan respons. Artikel ini menjelaskan komponen utama model delegasi, cara menggunakan peristiwa dalam aplikasi, dan cara menerapkan peristiwa dalam kode Anda.

Menaikkan peristiwa dengan pengirim peristiwa

Peristiwa adalah pesan yang dikirim oleh objek untuk memberi sinyal kemunculan tindakan. Tindakan ini mungkin interaksi pengguna, seperti penekanan tombol, atau mungkin dihasilkan dari logika program lain, seperti perubahan nilai properti. Objek yang menaikkan peristiwa disebut pengirim peristiwa . Pengirim peristiwa tidak mengetahui objek atau metode yang menerima (menangani) peristiwa yang dinaikkannya. Kejadian ini biasanya merupakan anggota pengirim peristiwa. Misalnya, peristiwa Click adalah anggota kelas Button, dan peristiwa PropertyChanged adalah anggota kelas yang mengimplementasikan antarmuka INotifyPropertyChanged.

Untuk mendefinisikan acara, Anda menggunakan kata kunci event dalam C# atau Event dalam Visual Basic di deklarasi kelas acara Anda, dan menetapkan jenis delegasi untuk acara tersebut. Delegasi dijelaskan di bagian berikutnya.

Biasanya, untuk menaikkan peristiwa, Anda menambahkan metode yang ditandai sebagai protected dan virtual (dalam C#) atau Protected dan Overridable (di Visual Basic). Konvensi penamaan untuk metode ini On<EventName>, seperti OnDataReceived. Metode harus mengambil satu parameter yang menentukan objek data peristiwa, yang merupakan objek jenis EventArgs atau jenis turunan. Anda menyediakan metode ini untuk memungkinkan kelas turunan mengambil alih logika untuk memicu peristiwa. Kelas turunan harus selalu memanggil metode On<EventName> kelas dasar untuk memastikan delegasi terdaftar menerima peristiwa.

Contoh berikut menunjukkan cara mendeklarasikan peristiwa bernama ThresholdReached. Peristiwa ini dikaitkan dengan delegasi EventHandler dan dimunculkan dalam metode bernama OnThresholdReached:

class Counter
{
    public event EventHandler ThresholdReached;

    protected virtual void OnThresholdReached(EventArgs e)
    {
        ThresholdReached?.Invoke(this, e);
    }

    // provide remaining implementation for the class
}
Public Class Counter
    Public Event ThresholdReached As EventHandler

    Protected Overridable Sub OnThresholdReached(e As EventArgs)
        RaiseEvent ThresholdReached(Me, e)
    End Sub

    ' provide remaining implementation for the class
End Class

Mendeklarasikan tanda tangan delegasi untuk penanganan aktivitas

Delegasi adalah jenis yang menyimpan referensi ke metode. Delegasi dideklarasikan dengan tanda tangan yang menunjukkan jenis pengembalian dan parameter untuk metode yang direferensikannya. Ini hanya dapat menyimpan referensi ke metode yang cocok dengan signaturnya. Delegasi setara dengan penunjuk fungsi jenis aman atau panggilan balik. Deklarasi delegasi cukup untuk menentukan kelas delegasi.

Delegasi memiliki banyak kegunaan dalam .NET. Dalam konteks peristiwa, delegasi adalah perantara (atau mekanisme seperti penunjuk) antara sumber peristiwa dan kode yang menangani peristiwa. Anda mengaitkan delegasi dengan peristiwa dengan menyertakan jenis delegasi dalam deklarasi peristiwa, seperti yang ditunjukkan pada contoh di bagian sebelumnya. Untuk informasi selengkapnya tentang delegasi, lihat kelas Delegate.

.NET menyediakan delegasi EventHandler dan EventHandler<TEventArgs> untuk mendukung sebagian besar skenario peristiwa. Gunakan delegasi EventHandler untuk semua acara yang tidak menyertakan data acara. Gunakan delegasi EventHandler<TEventArgs> untuk peristiwa yang menyertakan data tentang peristiwa tersebut. Delegasi ini tidak memiliki nilai tipe pengembalian dan menggunakan dua parameter (objek untuk sumber peristiwa dan objek untuk data peristiwa).

Delegat adalah kelas objek multicast, yang berarti mereka dapat menyimpan referensi ke lebih dari satu metode penanganan event. Untuk informasi selengkapnya, lihat halaman referensi Delegate. Delegasi memberikan fleksibilitas dan kontrol halus dalam penanganan peristiwa. Delegasi bertindak sebagai dispatcher peristiwa untuk kelas yang memicu peristiwa tersebut dengan mempertahankan daftar penangan peristiwa yang terdaftar.

Gunakan jenis delegasi EventHandler dan EventHandler<TEventArgs> untuk menentukan delegasi yang diperlukan. Anda menandai delegasi dengan delegate jenis di C# atau Delegate jenis di Visual Basic dalam deklarasi. Contoh berikut menunjukkan cara mendeklarasikan delegasi bernama ThresholdReachedEventHandler:

public delegate void ThresholdReachedEventHandler(object sender, ThresholdReachedEventArgs e);
Public Delegate Sub ThresholdReachedEventHandler(sender As Object, e As ThresholdReachedEventArgs)

Bekerja dengan kelas data peristiwa

Data yang terkait dengan peristiwa dapat disediakan melalui kelas data peristiwa. .NET menyediakan banyak kelas data peristiwa yang dapat Anda gunakan dalam aplikasi Anda. Misalnya, kelas SerialDataReceivedEventArgs adalah kelas data peristiwa untuk peristiwa SerialPort.DataReceived. .NET mengikuti pola penamaan di mana semua kelas data peristiwa diakhiri dengan akhiran EventArgs. Anda menentukan kelas data peristiwa mana yang dikaitkan dengan peristiwa dengan melihat delegasi untuk peristiwa tersebut. Misalnya, delegasi SerialDataReceivedEventHandler menyertakan kelas SerialDataReceivedEventArgs sebagai parameter.

Kelas EventArgs biasanya merupakan jenis dasar untuk kelas data peristiwa. Anda juga menggunakan kelas ini jika peristiwa tidak memiliki data apa pun yang terkait dengannya. Saat Anda membuat peristiwa yang memberi tahu pelanggan bahwa sesuatu terjadi tanpa data tambahan, sertakan kelas EventArgs sebagai parameter kedua dalam delegasi. Anda dapat meneruskan nilai EventArgs.Empty saat tidak ada data yang disediakan. Delegasi EventHandler menyertakan kelas EventArgs sebagai parameter.

Anda dapat membuat kelas yang berasal dari kelas EventArgs untuk menyediakan anggota apa pun yang diperlukan untuk meneruskan data yang terkait dengan peristiwa tersebut. Biasanya, Anda harus menggunakan pola penamaan yang sama dengan .NET dan mengakhiri nama kelas data peristiwa Anda dengan akhiran EventArgs.

Contoh berikut menunjukkan kelas data peristiwa bernama ThresholdReachedEventArgs yang berisi properti khusus untuk peristiwa yang dinaikkan:

public class ThresholdReachedEventArgs : EventArgs
{
    public int Threshold { get; set; }
    public DateTime TimeReached { get; set; }
}
Public Class ThresholdReachedEventArgs
    Inherits EventArgs

    Public Property Threshold As Integer
    Public Property TimeReached As DateTime
End Class

Menanggapi peristiwa dengan handler

Untuk menanggapi peristiwa, Anda menentukan metode penanganan aktivitas di penerima peristiwa. Metode ini harus cocok dengan tanda tangan delegasi untuk peristiwa yang Anda tangani. Pada penanganan peristiwa, Anda melakukan tindakan yang diperlukan saat peristiwa dipicu, seperti mengumpulkan input pengguna setelah pengguna menekan tombol. Untuk menerima pemberitahuan saat peristiwa terjadi, metode penanganan aktivitas Anda harus berlangganan peristiwa.

Contoh berikut menunjukkan metode penanganan aktivitas bernama c_ThresholdReached yang cocok dengan tanda tangan untuk delegasi EventHandler. Metode ini mendaftar ke peristiwa ThresholdReached:

class ProgramTwo
{
    static void Main()
    {
        var c = new Counter();
        c.ThresholdReached += c_ThresholdReached;

        // provide remaining implementation for the class
    }

    static void c_ThresholdReached(object sender, EventArgs e)
    {
        Console.WriteLine("The threshold was reached.");
    }
}
Module Module1

    Sub Main()
        Dim c As New Counter()
        AddHandler c.ThresholdReached, AddressOf c_ThresholdReached

        ' provide remaining implementation for the class
    End Sub

    Sub c_ThresholdReached(sender As Object, e As EventArgs)
        Console.WriteLine("The threshold was reached.")
    End Sub
End Module

Menggunakan penanganan aktivitas statis dan dinamis

.NET memungkinkan pelanggan untuk mendaftar untuk pemberitahuan peristiwa baik secara statis atau dinamis. Penanganan aktivitas statis berlaku untuk seluruh kehidupan kelas yang peristiwanya mereka tangani. Penanganan aktivitas dinamis diaktifkan dan dinonaktifkan secara eksplisit selama eksekusi program, biasanya sebagai respons terhadap beberapa logika program bersyarkat. Anda dapat menggunakan handler dinamis saat pemberitahuan peristiwa hanya diperlukan dalam kondisi tertentu, atau saat kondisi runtime menentukan handler tertentu untuk dipanggil. Contoh di bagian sebelumnya menunjukkan cara menambahkan penanganan aktivitas secara dinamis. Untuk informasi selengkapnya, lihat Peristiwa (di Visual Basic) dan Peristiwa (di C#).

Menaikkan beberapa peristiwa

Jika kelas Anda memicu beberapa event, pengompilasi menghasilkan satu bidang per instans delegasi event. Jika jumlah peristiwa besar, biaya penyimpanan satu bidang per delegasi mungkin tidak dapat diterima. Untuk skenario ini, .NET menyediakan properti peristiwa yang dapat Anda gunakan dengan struktur data lain pilihan Anda untuk menyimpan delegasi peristiwa.

Atribut peristiwa terdiri dari deklarasi peristiwa yang diikuti oleh pengakses peristiwa. Aksesor peristiwa adalah metode yang Anda tentukan untuk menambahkan atau menghapus instans delegasi peristiwa dari struktur data penyimpanan.

Nota

Properti peristiwa lebih lambat dari bidang peristiwa karena setiap delegasi peristiwa harus diambil sebelum dapat dipanggil.

Pertukaran adalah antara memori dan kecepatan. Jika kelas Anda menentukan banyak peristiwa yang jarang dimunculkan, Anda harus menerapkan properti peristiwa. Untuk informasi selengkapnya, lihat Menangani beberapa peristiwa dengan menggunakan properti peristiwa.

Sumber daya berikut menjelaskan tugas dan konsep lain yang terkait dengan bekerja dengan peristiwa:

Meninjau referensi spesifikasi

Dokumentasi referensi spesifikasi tersedia untuk API yang mendukung penanganan peristiwa:

Nama API Jenis API Referensi
EventHandler Mendelegasikan EventHandler
EventHandler<TEventArgs> Mendelegasikan EventHandler<TEventArgs>
EventArgs Kelas EventArgs
Mendelegasikan Kelas Delegate