Obsługa i wywoływanie zdarzeńHandling and raising events

Zdarzenia w programie .NET są oparte na modelu delegata.Events in .NET are based on the delegate model. Model delegata jest zgodny z wzorcem projektowym obserwatora, co umożliwia subskrybentowi zarejestrowanie się w usłudze i otrzymywanie powiadomień od dostawcy.The delegate model follows the observer design pattern, which enables a subscriber to register with and receive notifications from a provider. Nadawca zdarzeń wypychanie powiadomienia o wystąpieniu zdarzenia, a odbiorca zdarzenia odbiera to powiadomienie i definiuje odpowiedź na nie.An event sender pushes a notification that an event has happened, and an event receiver receives that notification and defines a response to it. W tym artykule opisano główne składniki modelu delegata, sposób korzystania ze zdarzeń w aplikacjach oraz sposób implementacji zdarzeń w kodzie.This article describes the major components of the delegate model, how to consume events in applications, and how to implement events in your code.

Aby uzyskać informacje na temat obsługi zdarzeń w aplikacjach ze sklepu Windows 8. x, zobacz Omówienie zdarzeń i zdarzeń kierowanych.For information about handling events in Windows 8.x Store apps, see Events and routed events overview.

ZdarzeniaEvents

Zdarzenie jest wiadomością wysłaną przez obiekt, aby sygnalizować wystąpienie akcji.An event is a message sent by an object to signal the occurrence of an action. Akcja może być spowodowana przez interakcję użytkownika, taką jak kliknięcie przycisku, lub może wynikać z innej logiki programu, takiej jak zmiana wartości właściwości.The action can be caused by user interaction, such as a button click, or it can result from some other program logic, such as changing a property’s value. Obiekt, który wywołuje zdarzenie, jest nazywany nadawcą zdarzenia.The object that raises the event is called the event sender. Nadawca zdarzenia nie wie, który obiekt lub metoda otrzyma (dojście) zdarzenia, które wywołuje.The event sender doesn't know which object or method will receive (handle) the events it raises. Zdarzenie jest zwykle członkiem nadawcy zdarzenia; na przykład zdarzenie Click jest członkiem klasy Button, a zdarzenie PropertyChanged jest członkiem klasy implementującej interfejs INotifyPropertyChanged.The event is typically a member of the event sender; for example, the Click event is a member of the Button class, and the PropertyChanged event is a member of the class that implements the INotifyPropertyChanged interface.

Aby zdefiniować zdarzenie, należy użyć C# słowa kluczowego event lub Visual Basic Event w sygnaturze klasy Event i określić typ delegata zdarzenia.To define an event, you use the C# event or the Visual Basic Event keyword in the signature of your event class, and specify the type of delegate for the event. Delegaty są opisane w następnej sekcji.Delegates are described in the next section.

Zwykle, aby zgłosić zdarzenie, należy dodać metodę, która jest oznaczona jako protected i virtual (in C#) lub Protected i Overridable (w Visual Basic).Typically, to raise an event, you add a method that is marked as protected and virtual (in C#) or Protected and Overridable (in Visual Basic). Nadaj nazwę tej metodzie OnEventName; na przykład OnDataReceived.Name this method OnEventName; for example, OnDataReceived. Metoda powinna przyjmować jeden parametr, który określa obiekt danych zdarzenia, który jest obiektem typu EventArgs lub typem pochodnym.The method should take one parameter that specifies an event data object, which is an object of type EventArgs or a derived type. Ta metoda umożliwia włączenie klas pochodnych w celu zastąpienia logiki w celu podniesienia poziomu zdarzenia.You provide this method to enable derived classes to override the logic for raising the event. Klasa pochodna zawsze powinna wywołać metodę OnEventName klasy bazowej, aby upewnić się, że zarejestrowani delegowani odbiera zdarzenie.A derived class should always call the OnEventName method of the base class to ensure that registered delegates receive the event.

Poniższy przykład pokazuje, jak zadeklarować zdarzenie o nazwie ThresholdReached.The following example shows how to declare an event named ThresholdReached. Zdarzenie jest skojarzone z delegatem EventHandler i wywoływane w metodzie o nazwie OnThresholdReached.The event is associated with the EventHandler delegate and raised in a method named 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

DelegatyDelegates

Delegat jest typem, który przechowuje odwołanie do metody.A delegate is a type that holds a reference to a method. Delegat jest zadeklarowany za pomocą podpisu, który pokazuje zwracany typ i parametry dla metod, do których się odwołuje, i może zawierać odwołania tylko do metod, które pasują do podpisu.A delegate is declared with a signature that shows the return type and parameters for the methods it references, and it can hold references only to methods that match its signature. Delegat jest analogiczny do wskaźnika funkcji bezpiecznego typu lub wywołania zwrotnego.A delegate is thus equivalent to a type-safe function pointer or a callback. Deklaracja delegata jest wystarczająca do zdefiniowania klasy delegata.A delegate declaration is sufficient to define a delegate class.

Delegaty mają wiele użycia w programie .NET.Delegates have many uses in .NET. W kontekście zdarzeń delegat jest pośrednim (lub mechanizmem podobnym do wskaźnika) między źródłem zdarzenia a kodem, który obsługuje zdarzenie.In the context of events, a delegate is an intermediary (or pointer-like mechanism) between the event source and the code that handles the event. Można skojarzyć delegata ze zdarzeniem, dołączając typ delegata w deklaracji zdarzenia, jak pokazano w przykładzie w poprzedniej sekcji.You associate a delegate with an event by including the delegate type in the event declaration, as shown in the example in the previous section. Aby uzyskać więcej informacji na temat delegatów, zobacz Klasa Delegate.For more information about delegates, see the Delegate class.

Platforma .NET udostępnia delegatów EventHandler i EventHandler<TEventArgs> do obsługi większości scenariuszy zdarzeń..NET provides the EventHandler and EventHandler<TEventArgs> delegates to support most event scenarios. Dla wszystkich zdarzeń, które nie zawierają danych zdarzenia, należy użyć delegata EventHandler.Use the EventHandler delegate for all events that do not include event data. Użyj delegata EventHandler<TEventArgs> dla zdarzeń, które zawierają dane dotyczące zdarzenia.Use the EventHandler<TEventArgs> delegate for events that include data about the event. Te Delegaty nie mają wartości zwracanego typu i przyjmują dwa parametry (obiekt dla źródła zdarzenia i obiekt dla danych zdarzenia).These delegates have no return type value and take two parameters (an object for the source of the event, and an object for event data).

Delegaty są multiemisją, co oznacza, że mogą przechowywać odwołania do więcej niż jednej metody obsługi zdarzeń.Delegates are multicast, which means that they can hold references to more than one event-handling method. Aby uzyskać szczegółowe informacje, zobacz stronę referencyjną Delegate.For details, see the Delegate reference page. Delegaty zapewniają elastyczność i szczegółową kontrolę w obsłudze zdarzeń.Delegates provide flexibility and fine-grained control in event handling. Delegat działa jako Dyspozytor zdarzeń dla klasy, która wywołuje zdarzenie przez utrzymywanie listy zarejestrowanych programów obsługi zdarzeń dla zdarzenia.A delegate acts as an event dispatcher for the class that raises the event by maintaining a list of registered event handlers for the event.

W scenariuszach, w których EventHandler i EventHandler<TEventArgs> delegatów nie działają, można zdefiniować delegata.For scenarios where the EventHandler and EventHandler<TEventArgs> delegates do not work, you can define a delegate. Scenariusze, które wymagają zdefiniowania delegata, są bardzo rzadkimi, na przykład gdy trzeba współpracować z kodem, który nie rozpoznaje typów ogólnych.Scenarios that require you to define a delegate are very rare, such as when you must work with code that does not recognize generics. Delegat można oznaczyć za pomocą C# słowa kluczowego delegate i Visual Basic Delegate w deklaracji.You mark a delegate with the C# delegate and Visual Basic Delegate keyword in the declaration. Poniższy przykład pokazuje, jak zadeklarować delegata o nazwie ThresholdReachedEventHandler.The following example shows how to declare a delegate named ThresholdReachedEventHandler.

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

Dane zdarzeniaEvent data

Dane skojarzone ze zdarzeniem mogą być dostarczane za pomocą klasy danych zdarzenia.Data that is associated with an event can be provided through an event data class. Platforma .NET udostępnia wiele klas danych zdarzeń, których można używać w aplikacjach..NET provides many event data classes that you can use in your applications. Na przykład Klasa SerialDataReceivedEventArgs jest klasą danych zdarzenia dla zdarzenia SerialPort.DataReceived.For example, the SerialDataReceivedEventArgs class is the event data class for the SerialPort.DataReceived event. .NET stosuje wzorzec nazewnictwa kończący wszystkie klasy danych zdarzeń z EventArgs..NET follows a naming pattern of ending all event data classes with EventArgs. Należy określić, która Klasa danych zdarzenia jest skojarzona ze zdarzeniem, przeglądając delegata zdarzenia.You determine which event data class is associated with an event by looking at the delegate for the event. Na przykład delegat SerialDataReceivedEventHandler zawiera klasę SerialDataReceivedEventArgs jako jeden z jej parametrów.For example, the SerialDataReceivedEventHandler delegate includes the SerialDataReceivedEventArgs class as one of its parameters.

Klasa EventArgs jest typem podstawowym dla wszystkich klas danych zdarzeń.The EventArgs class is the base type for all event data classes. EventArgs jest również klasą używaną, gdy do zdarzenia nie są skojarzone żadne dane.EventArgs is also the class you use when an event does not have any data associated with it. Podczas tworzenia zdarzenia, które jest przeznaczone tylko do powiadamiania innych klas, których coś dotyczy, i nie musi przekazywać żadnych danych, należy uwzględnić klasę EventArgs jako drugi parametr w delegatze.When you create an event that is only meant to notify other classes that something happened and does not need to pass any data, include the EventArgs class as the second parameter in the delegate. Można przekazać wartość EventArgs.Empty, gdy nie są dostarczane żadne dane.You can pass the EventArgs.Empty value when no data is provided. Delegat EventHandler zawiera klasę EventArgs jako parametr.The EventHandler delegate includes the EventArgs class as a parameter.

Jeśli chcesz utworzyć dostosowaną klasę danych zdarzenia, Utwórz klasę pochodzącą z EventArgs, a następnie podaj wszelkich członków, którzy będą musieli przekazać dane związane ze zdarzeniem.When you want to create a customized event data class, create a class that derives from EventArgs, and then provide any members needed to pass data that is related to the event. Zazwyczaj należy używać tego samego wzorca nazewnictwa jak .NET i kończyć nazwę klasy danych zdarzenia z EventArgs.Typically, you should use the same naming pattern as .NET and end your event data class name with EventArgs.

Poniższy przykład pokazuje klasę danych zdarzenia o nazwie ThresholdReachedEventArgs.The following example shows an event data class named ThresholdReachedEventArgs. Zawiera właściwości, które są specyficzne dla wywoływanego zdarzenia.It contains properties that are specific to the event being raised.

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

Programy obsługi zdarzeńEvent handlers

Aby odpowiedzieć na zdarzenie, należy zdefiniować metodę obsługi zdarzeń w odbiorcy zdarzeń.To respond to an event, you define an event handler method in the event receiver. Ta metoda musi być zgodna z sygnaturą delegata dla zdarzenia, które jest obsługiwane.This method must match the signature of the delegate for the event you are handling. W programie obsługi zdarzeń wykonywane są akcje, które są wymagane w przypadku zgłoszenia zdarzenia, takie jak zbieranie danych wejściowych przez użytkownika po kliknięciu przycisku.In the event handler, you perform the actions that are required when the event is raised, such as collecting user input after the user clicks a button. Aby otrzymywać powiadomienia, gdy wystąpi zdarzenie, metoda obsługi zdarzeń musi subskrybować zdarzenie.To receive notifications when the event occurs, your event handler method must subscribe to the event.

Poniższy przykład przedstawia metodę procedury obsługi zdarzeń o nazwie c_ThresholdReached, która pasuje do sygnatury EventHandler delegata.The following example shows an event handler method named c_ThresholdReached that matches the signature for the EventHandler delegate. Metoda subskrybuje zdarzenie ThresholdReached.The method subscribes to the ThresholdReached event.

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

Procedury obsługi zdarzeń statycznych i dynamicznychStatic and dynamic event handlers

Platforma .NET umożliwia subskrybentom rejestrację powiadomień o zdarzeniach statycznie lub dynamicznie..NET allows subscribers to register for event notifications either statically or dynamically. Procedury obsługi zdarzeń statycznych są stosowane dla całego okresu istnienia klasy, której zdarzenia obsługują.Static event handlers are in effect for the entire life of the class whose events they handle. Procedury obsługi zdarzeń dynamicznych są jawnie uaktywniane i dezaktywowane podczas wykonywania programu, zazwyczaj w odpowiedzi na niektóre logiki programu warunkowego.Dynamic event handlers are explicitly activated and deactivated during program execution, usually in response to some conditional program logic. Można na przykład użyć ich w przypadku, gdy powiadomienia o zdarzeniach są wymagane tylko w określonych warunkach lub jeśli aplikacja zawiera wiele programów obsługi zdarzeń, a warunki czasu wykonywania definiują odpowiednią wartość do użycia.For example, they can be used if event notifications are needed only under certain conditions or if an application provides multiple event handlers and run-time conditions define the appropriate one to use. W przykładzie w poprzedniej sekcji pokazano, jak dynamicznie dodać program obsługi zdarzeń.The example in the previous section shows how to dynamically add an event handler. Aby uzyskać więcej informacji, zobacz zdarzenia (w Visual Basic) i zdarzenia ( C#w programie).For more information, see Events (in Visual Basic) and Events (in C#).

Wywoływanie wielu zdarzeńRaising multiple events

Jeśli Klasa wywołuje wiele zdarzeń, kompilator generuje jedno pole na wystąpienie delegata zdarzenia.If your class raises multiple events, the compiler generates one field per event delegate instance. Jeśli liczba zdarzeń jest duża, koszt magazynowania jednego pola na delegata może nie być akceptowalny.If the number of events is large, the storage cost of one field per delegate may not be acceptable. W takich sytuacjach platforma .NET udostępnia właściwości zdarzeń, które mogą być używane z inną strukturą danych, która umożliwia przechowywanie delegatów zdarzeń.For those situations, .NET provides event properties that you can use with another data structure of your choice to store event delegates.

Właściwości zdarzenia składają się z deklaracji zdarzeń, które towarzyszą metodom dostępu do zdarzeń.Event properties consist of event declarations accompanied by event accessors. Metody dostępu zdarzeń są zdefiniowane w celu dodawania lub usuwania wystąpień delegatów zdarzeń ze struktury danych magazynu.Event accessors are methods that you define to add or remove event delegate instances from the storage data structure. Należy pamiętać, że właściwości zdarzeń są wolniejsze od pól zdarzeń, ponieważ każdy delegat zdarzenia musi zostać pobrany, aby można było go wywołać.Note that event properties are slower than event fields, because each event delegate must be retrieved before it can be invoked. Handel jest między pamięcią a szybkością.The trade-off is between memory and speed. Jeśli klasa definiuje wiele zdarzeń, które są rzadko zgłaszane, należy zaimplementować właściwości zdarzenia.If your class defines many events that are infrequently raised, you will want to implement event properties. Aby uzyskać więcej informacji, zobacz How to: obsługa wielu zdarzeń przy użyciu właściwości zdarzenia.For more information, see How to: Handle Multiple Events Using Event Properties.

TytułTitle OpisDescription
Instrukcje: Wywoływanie zdarzeń i korzystanie z nichHow to: Raise and Consume Events Zawiera przykłady podnoszenia i zużywania zdarzeń.Contains examples of raising and consuming events.
Instrukcje: Obsługa wielu zdarzeń przy użyciu właściwości zdarzeniaHow to: Handle Multiple Events Using Event Properties Pokazuje, jak używać właściwości zdarzenia do obsługi wielu zdarzeń.Shows how to use event properties to handle multiple events.
Wzorzec projektowy obserwatoraObserver Design Pattern Opisuje Wzorzec projektowy, który umożliwia subskrybentowi zarejestrowanie się w usłudze i otrzymywanie powiadomień od dostawcy.Describes the design pattern that enables a subscriber to register with, and receive notifications from, a provider.
Instrukcje: Korzystanie ze zdarzeń w aplikacjach formularzy internetowychHow to: Consume Events in a Web Forms Application Pokazuje, jak obsłużyć zdarzenie, które jest wywoływane przez formant formularzy sieci Web.Shows how to handle an event that is raised by a Web Forms control.

Zobacz takżeSee also