Zpracování a vyvolávání událostí
Události v .NET jsou založené na modelu delegáta. Model delegáta se řídí vzorem návrhu pozorovatele, který umožňuje předplatiteli zaregistrovat se a přijímat oznámení od poskytovatele. Odesílatel události odešle oznámení, že se událost stala, a příjemce události obdrží toto oznámení a definuje odpověď na ni. Tento článek popisuje hlavní součásti modelu delegáta, jak využívat události v aplikacích a jak implementovat události v kódu.
událost
Událost je zpráva odeslaná objektem, která signalizovala výskyt akce. Akce může být způsobená interakcí uživatele, například kliknutím na tlačítko, nebo může mít za následek jinou logiku programu, například změnu hodnoty vlastnosti. Objekt, který vyvolá událost, se nazývá odesílatel události. Odesílatel události neví, který objekt nebo metoda obdrží (zpracuje) události, které vyvolá. Událost je obvykle členem odesílatele události; Click Například událost je členem Button třídy a PropertyChanged událost je členem třídy, která implementuje INotifyPropertyChanged rozhraní.
K definování události použijete klíčové slovo C# event
nebo Visual Basic Event
v podpisu třídy událostí a zadáte typ delegáta události. Delegáti jsou popsáni v další části.
K vyvolání události obvykle přidáte metodu označenou jako protected
a virtual
(v jazyce C#) nebo Protected
Overridable
(v Visual Basic). Pojmenujte tuto metodu On
EventName, například OnDataReceived
. Metoda by měla mít jeden parametr, který určuje datový objekt události, což je objekt typu EventArgs nebo odvozený typ. Tuto metodu zadáte tak, aby odvozené třídy přepsaly logiku pro vyvolání události. Odvozená třída by měla vždy volat metodu On
EventName základní třídy, aby se zajistilo, že zaregistrovaní delegáti obdrží událost.
Následující příklad ukazuje, jak deklarovat událost pojmenovanou ThresholdReached
. Událost je přidružena delegátovi EventHandler a vyvolána v metodě s názvem 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
Delegáti
Delegát je typ, který obsahuje odkaz na metodu. Delegát je deklarován podpisem, který zobrazuje návratový typ a parametry pro metody, na které odkazuje, a může obsahovat odkazy pouze na metody, které odpovídají jeho podpisu. Delegát je tedy ekvivalentní ukazateli funkce bezpečného typu nebo zpětnému volání. Deklarace delegáta je dostatečná k definování třídy delegáta.
Delegáti mají mnoho použití v .NET. V kontextu událostí je delegát mezi zdrojem událostí a kódem, který zpracovává událost, zprostředkující (nebo mechanismus podobný ukazateli). Delegáta přidružíte k události zahrnutím typu delegáta do deklarace události, jak je znázorněno v příkladu v předchozí části. Další informace odelegátch Delegate
.NET poskytuje EventHandler a EventHandler<TEventArgs> delegáty pro podporu většiny scénářů událostí. Použijte delegáta EventHandler pro všechny události, které neobsahují data událostí. Použijte delegáta EventHandler<TEventArgs> pro události, které obsahují data o události. Tito delegáti nemají žádnou návratovou hodnotu typu a přebírají dva parametry (objekt pro zdroj události a objekt pro data události).
Delegáti jsou vícesměrové vysílání, což znamená, že můžou obsahovat odkazy na více než jednu metodu zpracování událostí. Podrobnosti najdete na Delegate referenční stránce. Delegáti poskytují flexibilitu a jemně odstupňované řízení při zpracování událostí. Delegát funguje jako dispečer událostí pro třídu, která vyvolá událost tím, že udržuje seznam registrovaných obslužných rutin událostí pro událost.
V situacích, kdy EventHandler delegáti EventHandler<TEventArgs> nefungují, můžete definovat delegáta. Scénáře, které vyžadují, abyste definovali delegáta, jsou velmi vzácné, například když musíte pracovat s kódem, který nerozpozná obecné typy. Delegáta označíte pomocí jazyka C# delegate
a Visual Basic Delegate
klíčové slovo v deklaraci. Následující příklad ukazuje, jak deklarovat delegáta s názvem ThresholdReachedEventHandler
.
public delegate void ThresholdReachedEventHandler(object sender, ThresholdReachedEventArgs e);
Public Delegate Sub ThresholdReachedEventHandler(sender As Object, e As ThresholdReachedEventArgs)
Data událostí
Data přidružená k události je možné poskytnout prostřednictvím datové třídy události. .NET poskytuje mnoho datových tříd událostí, které můžete použít ve svých aplikacích. Třída je například SerialDataReceivedEventArgs datová třída události pro SerialPort.DataReceived událost. .NET se řídí vzorem pojmenování ukončení všech datových tříd událostí .EventArgs
Určíte, která datová třída událostí je přidružená k události, a to tak, že se podíváte na delegáta události. Delegát například SerialDataReceivedEventHandler obsahuje SerialDataReceivedEventArgs třídu jako jeden z jeho parametrů.
Třída EventArgs je základním typem pro všechny třídy dat událostí. EventArgs je také třída, kterou používáte, pokud událost nemá přidružená žádná data. Když vytvoříte událost, která je určená pouze k upozornění jiných tříd, že se něco stalo a nemusí předávat žádná data, zahrňte EventArgs třídu jako druhý parametr delegáta. Hodnotu můžete předat EventArgs.Empty , pokud nejsou k dispozici žádná data. Delegát EventHandler zahrnuje EventArgs třídu jako parametr.
Pokud chcete vytvořit přizpůsobenou datovou třídu událostí, vytvořte třídu, která je odvozena od EventArgs, a pak zadejte všechny členy potřebné k předávání dat, která souvisejí s událostí. Obvykle byste měli použít stejný vzor pojmenování jako .NET a ukončit název třídy dat události .EventArgs
Následující příklad ukazuje datovou třídu události s názvem ThresholdReachedEventArgs
. Obsahuje vlastnosti specifické pro vyvolání události.
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
Obslužné rutiny událostí
Chcete-li reagovat na událost, definujete metodu obslužné rutiny události v přijímači událostí. Tato metoda musí odpovídat podpisu delegáta pro událost, kterou zpracováváte. V obslužné rutině události provedete akce potřebné při vyvolání události, například shromažďování uživatelského vstupu po kliknutí na tlačítko. Pokud chcete dostávat oznámení, když dojde k události, musí se vaše metoda obslužné rutiny události přihlásit k odběru události.
Následující příklad ukazuje metodu obslužné rutiny události s názvem c_ThresholdReached
, která odpovídá podpisu delegáta EventHandler . Metoda se přihlásí k odběru ThresholdReached
události.
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
Statické a dynamické obslužné rutiny událostí
.NET umožňuje předplatitelům registrovat oznámení událostí staticky nebo dynamicky. Statické obslužné rutiny událostí se projeví po celou dobu životnosti třídy, jejíž události zpracovávají. Dynamické obslužné rutiny událostí se explicitně aktivují a deaktivují během provádění programu, obvykle v reakci na nějakou logiku podmíněného programu. Dají se například použít, pokud jsou oznámení událostí potřebná pouze za určitých podmínek nebo pokud aplikace poskytuje více obslužných rutin událostí a podmínky běhu definují odpovídající, které se mají použít. Příklad v předchozí části ukazuje, jak dynamicky přidat obslužnou rutinu události. Další informace najdete v tématu Události (v Visual Basic) a Události (v jazyce C#).
Vyvolání více událostí
Pokud vaše třída vyvolá více událostí, kompilátor vygeneruje jedno pole pro instanci delegáta události. Pokud je počet událostí velký, náklady na úložiště jednoho pole na delegáta nemusí být přijatelné. V takových situacích poskytuje .NET vlastnosti událostí, které můžete použít s jinou datovou strukturou podle vašeho výběru k ukládání delegátů událostí.
Vlastnosti události se skládají z deklarací událostí doprovázených příslušenstvím událostí. Přístupové objekty událostí jsou metody, které definujete pro přidání nebo odebrání instancí delegátů událostí ze struktury dat úložiště. Všimněte si, že vlastnosti událostí jsou pomalejší než pole událostí, protože každý delegát události musí být načten před vyvolání. Kompromis je mezi pamětí a rychlostí. Pokud vaše třída definuje mnoho událostí, které jsou zřídka vyvolány, budete chtít implementovat vlastnosti události. Další informace naleznete v tématu Postupy: Zpracování více událostí pomocí vlastností události.
Související články
Nadpis | Popis |
---|---|
Postupy: Vyvolávání a zpracovávání událostí | Obsahuje příklady vyvolání a využívání událostí. |
Postupy: Zpracování více událostí pomocí vlastností událostí | Ukazuje, jak pomocí vlastností událostí zpracovat více událostí. |
Vzor návrhu pozorovatele | Popisuje vzor návrhu, který předplatiteli umožňuje registraci a přijímání oznámení od poskytovatele. |