Menangani dan memunculkan kejadian

Kejadian di .NET didasarkan pada model delegasi. Model delegasi mengikuti pola desain pengamat, sehingga orang yang berlangganan dapat mendaftar dan menerima pemberitahuan dari penyedia. Pengirim kejadian mendorong pemberitahuan bahwa ada kejadian yang telah terjadi, dan penerima kejadian menerima pemberitahuan tersebut dan menentukan respons terhadapnya. Artikel ini menjelaskan komponen utama model delegasi, cara memakai kejadian dalam aplikasi, serta cara menerapkan kejadian dalam kode Anda.

Acara

Kejadian adalah pesan yang dikirim oleh objek untuk menandakan terjadinya suatu tindakan. Tindakan tersebut dapat disebabkan oleh interaksi pengguna, misalnya klik pada tombol, atau dapat dihasilkan dari beberapa logika program lain, seperti mengubah nilai properti. Objek yang memunculkan kejadian disebut sebagai pengirim kejadian. Pengirim kejadian tidak tahu objek atau metode mana yang akan menerima (menangani) kejadian yang dimunculkannya. Kejadian ini biasanya merupakan anggota pengirim kejadian; misalnya, kejadian Click adalah anggota kelas Button, dan kejadian PropertyChanged adalah anggota kelas yang mengimplementasikan antarmuka INotifyPropertyChanged.

Untuk menentukan kejadian, Anda menggunakan event C# atau kata kunci Event Visual Basic di tanda tangan kelas kejadian Anda, dan menentukan jenis delegasi kejadian tersebut. Delegasi dijelaskan di bagian berikutnya.

Biasanya, untuk memunculkan kejadian, Anda akan menambahkan metode yang ditandai sebagai protected dan virtual (dalam C#) atau Protected dan Overridable (di Visual Basic). Beri nama metode ini sebagai OnEventName; misalnya, OnDataReceived. Metode tersebut harus mengambil satu parameter yang menentukan objek data kejadian, yang merupakan objek jenis EventArgs atau jenis turunan. Anda menyediakan metode ini agar kelas turunan dapat mengambil alih logika untuk memunculkan kejadian. Kelas turunan harus selalu memanggil On metode EventName dari kelas dasar untuk memastikan bahwa delegasi yang sudah terdaftar menerima kejadian tersebut.

Contoh berikut menunjukkan cara mendeklarasikan kejadian bernama ThresholdReached. Kejadian ini dikaitkan dengan delegasi EventHandler dan dimunculkan dalam metode bernama OnThresholdReached.

class Counter
{
    public event EventHandler ThresholdReached;

    protected virtual void OnThresholdReached(EventArgs e)
    {
        EventHandler handler = ThresholdReached;
        handler?.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

Delegasikan

Delegasi adalah jenis yang memiliki referensi ke suatu metode. Delegasi dideklarasikan dengan tanda tangan yang menunjukkan jenis tampilan dan parameter metode yang dijadikan referensi, dan delegasi hanya dapat menyimpan referensi ke metode yang sesuai dengan tanda tangannya. Sehingga, delegasi setara dengan penunjuk fungsi yang aman bagi jenis atau panggilan balik. Deklarasi delegasi sudah cukup untuk menentukan kelas delegasi.

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

.NET menyediakan delegasi EventHandler dan EventHandler<TEventArgs> untuk mendukung sebagian besar skenario kejadian. Gunakan delegasi EventHandler untuk semua kejadian yang tidak menyertakan data kejadian. Gunakan delegasi EventHandler<TEventArgs> untuk kejadian yang menyertakan data terkait kejadian tersebut. Delegasi ini tidak memiliki nilai jenis tampilan dan mengambil dua parameter (objek untuk sumber kejadian, serta objek untuk data kejadian).

Delegasi bersifat multicast, yang berarti bahwa delegasi dapat menyimpan referensi ke lebih dari satu metode pengendalian kejadian. Untuk detailnya, lihat halaman referensi Delegate. Delegasi memberikan fleksibilitas dan kontrol yang sangat rinci dalam pengendalian kejadian. Delegasi bertindak sebagai pekerja kejadian untuk kelas yang memunculkan kejadian dengan mempertahankan daftar pengendali kejadian yang sudah terdaftar untuk kejadian tersebut.

Saat delegasi EventHandler dan EventHandler<TEventArgs> tidak berfungsi, Anda dapat menentukan delegasi. Skenario yang mengharuskan Anda untuk menentukan delegasi sangat jarang, seperti ketika Anda harus menggunakan kode yang tidak mengenali generik. Anda menandai delegasi dengan delegate C# dan kata kunci Delegate 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)

Data kejadian

Data yang terkait dengan suatu kejadian dapat diberikan melalui kelas data kejadian. .NET menyediakan banyak kelas data kejadian yang dapat Anda gunakan di aplikasi Anda. Misalnya, kelas SerialDataReceivedEventArgs adalah kelas data kejadian untuk kejadian SerialPort.DataReceived. .NET mengikuti pola penamaan yang mengakhiri semua kelas data kejadian dengan EventArgs. Anda menentukan kelas data kejadian mana yang terkait dengan suatu kejadian dengan melihat delegasi kejadian tersebut. Misalnya, delegasi SerialDataReceivedEventHandler menyertakan kelas SerialDataReceivedEventArgs sebagai salah satu parameternya.

Kelas EventArgs adalah jenis dasar semua kelas data kejadian. EventArgs juga merupakan kelas yang Anda gunakan ketika suatu kejadian tidak memiliki data apa pun yang terkait dengannya. Saat Anda membuat kejadian yang hanya ditujukan untuk memberi tahu kelas lain bahwa ada sesuatu yang terjadi dan tidak perlu meneruskan data apa pun, sertakan kelas EventArgs sebagai parameter kedua dalam delegasi. Anda dapat meneruskan nilai EventArgs.Empty ketika tidak ada data yang disediakan. Delegasi EventHandler menyertakan kelas EventArgs sebagai parameter.

Saat Anda ingin membuat kelas data kejadian yang dikustomisasi, buat kelas yang berasal dari EventArgs, lalu berikan anggota yang diperlukan untuk meneruskan data yang terkait dengan kejadian tersebut. Biasanya, Anda harus menggunakan pola penamaan yang sama dengan .NET dan mengakhiri nama kelas data kejadian Anda dengan EventArgs.

Contoh berikut menunjukkan kelas data kejadian bernama ThresholdReachedEventArgs. Kelas tersebut berisi properti yang bersifat khusus untuk kejadian yang dimunculkan.

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

Penangan kejadian

Untuk menanggapi suatu kejadian, Anda menentukan metode pengendalian aktivitas di penerima kejadian. Metode ini harus sesuai dengan tanda tangan delegasi kejadian yang sedang Anda tangani. Di pengendali aktivitas, Anda melakukan tindakan yang diperlukan saat kejadian dimunculkan, seperti mengumpulkan input pengguna setelah pengguna mengklik tombol. Untuk menerima pemberitahuan saat kejadian terjadi, metode pengendalian aktivitas Anda harus berlangganan ke kejadian tersebut.

Contoh berikut menunjukkan metode pengendalian aktivitas bernama c_ThresholdReached yang cocok dengan tanda tangan delegasi EventHandler. Metode tersebut berlangganan ke kejadian ThresholdReached.

class Program
{
    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

Pengendalian aktivitas statik dan dinamis

.NET mengizinkan agar orang yang berlangganan dapat mendaftar pemberitahuan kejadian, baik secara statik maupun dinamis. Pengendalian aktivitas statik berlaku untuk seluruh masa pakai kelas yang kejadiannya mereka tangani. Pengendalian aktivitas dinamis secara eksplisit diaktifkan dan dinonaktifkan selama eksekusi program, yang biasanya merupakan respons terhadap beberapa logika program bersyarat. Misalnya, pengendalian aktivitas tersebut dapat digunakan jika pemberitahuan kejadian hanya diperlukan dalam kondisi tertentu, atau jika aplikasi menyediakan beberapa pengendalian aktivitas dan kondisi run-time menentukan pengendalian aktivitas yang sesuai untuk digunakan. Contoh di bagian sebelumnya menunjukkan cara menambahkan pengendalian aktivitas secara dinamis. Untuk informasi lebih lanjut, lihat Kejadian (di Visual Basic) dan Kejadian (di C#).

Memunculkan beberapa kejadian

Jika kelas Anda memunculkan beberapa kejadian, pengompilasi akan menghasilkan satu bidang untuk satu instans delegasi kejadian. Jika jumlah kejadiannya besar, biaya penyimpanan satu bidang per delegasi mungkin tidak akan dapat diterima. Dalam situasi seperti itu, .NET menyediakan properti kejadian yang dapat Anda gunakan dengan struktur data lain pilihan Anda untuk menyimpan delegasi kejadian.

Properti kejadian terdiri dari deklarasi kejadian yang disertai dengan pengakses kejadian. Pengakses kejadian adalah metode yang Anda tentukan untuk menambahkan atau menghapus instans delegasi kejadian dari struktur data penyimpanan. Perhatikan bahwa properti kejadian lebih lambat dari bidang kejadian, karena setiap delegasi kejadian harus diambil sebelum dapat dipanggil. Sedangkan konsekuensinya adalah antara memori dan kecepatan. Jika kelas Anda menentukan banyak kejadian yang jarang dimunculkan, sebaiknya terapkan properti kejadian. Untuk informasi lebih lanjut, lihat Panduan: Menangani Beberapa Kejadian Menggunakan Properti Kejadian.

Judul Deskripsi
Panduan: Memunculkan dan Memakai Kejadian Berisi contoh tindakan memunculkan dan menggunakan kejadian.
Panduan: Menangani Beberapa Kejadian Menggunakan Properti Kejadian Menunjukkan cara menggunakan properti kejadian untuk menangani beberapa kejadian.
Pola Desain Pengamat Menjelaskan pola desain sehingga orang yang berlangganan dapat mendaftar dan menerima pemberitahuan dari penyedia.

Lihat juga