Gestione e generazione di eventiHandling and Raising Events

Gli eventi in .NET Framework si basano sul modello di delegato.Events in the .NET Framework are based on the delegate model. Il modello di delegato segue lo schema progettuale osservatore, che consente a un sottoscrittore di effettuare la registrazione con e ricevere notifiche da un provider.The delegate model follows the observer design pattern, which enables a subscriber to register with, and receive notifications from, a provider. Un mittente dell'evento esegue il push di una notifica di evento, mentre un ricevitore di eventi riceve la notifica e definisce una risposta.An event sender pushes a notification that an event has happened, and an event receiver receives that notification and defines a response to it. In questo articolo viene descritto come implementare gli eventi nel codice, come usare gli eventi nelle applicazioni e i componenti principali del modello di delegato.This article describes the major components of the delegate model, how to consume events in applications, and how to implement events in your code.

Per informazioni sulla gestione di eventi nelle applicazioni Windows 8.x Store, vedere la pagina relativa alla Panoramica degli eventi e degli eventi indirizzati.For information about handling events in Windows 8.x Store apps, see Events and routed events overview.

EventiEvents

Un evento è un messaggio inviato da un oggetto per segnalare l'occorrenza di un'azione.An event is a message sent by an object to signal the occurrence of an action. L'azione può essere causata dall'interazione dell'utente, ad esempio la pressione di un pulsante, oppure generata da altre logiche di programma, ad esempio la modifica di un valore della proprietà.The action could be caused by user interaction, such as a button click, or it could be raised by some other program logic, such as changing a property’s value. L'oggetto che genera l'evento viene chiamato mittente dell'evento.The object that raises the event is called the event sender. Il mente dell'evento non sa quale oggetto o metodo riceverà (handle) gli eventi che egli genera.The event sender doesn't know which object or method will receive (handle) the events it raises. L'evento è in genere un membro del mittente dell'evento. Ad esempio, l'evento Click è un membro della classe Button e l'evento PropertyChanged è un membro della classe che implementa l'interfaccia 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.

Per definire un evento, usare la parola chiave event (in C#) o Event (in Visual Basic) nella firma della classe dell'evento e specificare il tipo di delegato per l'evento.To define an event, you use the event (in C#) or Event (in Visual Basic) keyword in the signature of your event class, and specify the type of delegate for the event. I delegati vengono descritti nella sezione successiva.Delegates are described in the next section.

In genere, per generare un evento, aggiungere un metodo contrassegnato come protected e virtual (in C#) o Protected e Overridable (in 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). Denominare il metodo OnNomeEvento; ad esempio, OnDataReceived.Name this method OnEventName; for example, OnDataReceived. Il metodo deve accettare un parametro che specifica un oggetto dati dell'evento.The method should take one parameter that specifies an event data object. Fornire questo metodo per consentire alle classi derivate di sostituire la logica per la generazione dell'evento.You provide this method to enable derived classes to override the logic for raising the event. Affinché l'evento sia ricevuto da delegati registrati, occorre che tramite una classe derivata venga sempre chiamato il metodo OnNomeEvento della classe di base.A derived class should always call the OnEventName method of the base class to ensure that registered delegates receive the event.

Nell'esempio riportato di seguito viene illustrato come dichiarare un evento denominato ThresholdReached.The following example shows how to declare an event named ThresholdReached. L'evento è associato al delegatoEventHandler e generato in un metodo denominato 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;
        if (handler != null)
        {
            handler(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

DelegatiDelegates

Un delegato è un tipo che contiene un riferimento a un metodo.A delegate is a type that holds a reference to a method. Un delegato è dichiarato con una firma che mostra il tipo restituito e i parametri per i metodi a cui fa riferimento e può contenere riferimenti solo per i metodi che corrispondono alla firma.A delegate is declared with a signature that shows the return type and parameters for the methods it references, and can hold references only to methods that match its signature. Un delegato è pertanto equivalente a un puntatore a funzione indipendente dai tipi o un callback.A delegate is thus equivalent to a type-safe function pointer or a callback. Una dichiarazione di delegato è sufficiente per definire una classe delegata.A delegate declaration is sufficient to define a delegate class.

Sono molti gli usi dei delegati in .NET Framework.Delegates have many uses in the .NET Framework. Nel contesto degli eventi, un delegato è un intermediario (o meccanismo di tipo puntatore) tra l'origine evento e il codice che gestisce l'evento.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. Associare un delegato a un evento, incluso il tipo di delegato nella dichiarazione di evento, come illustrato nell'esempio nella sezione precedente.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. Per altre informazioni sui delegati, vedere la classe Delegate.For more information about delegates, see the Delegate class.

.NET Framework fornisce i delegati EventHandler e EventHandler<TEventArgs> per supportare la maggior parte degli scenari per gli eventi.The .NET Framework provides the EventHandler and EventHandler<TEventArgs> delegates to support most event scenarios. Usare il delegato EventHandler per tutti gli eventi che non includono dati dell'evento.Use the EventHandler delegate for all events that do not include event data. Usare il delegato EventHandler<TEventArgs> per eventi che includono dati sull'evento.Use the EventHandler<TEventArgs> delegate for events that include data about the event. Questi delegati non hanno alcun valore di tipo restituito e accettano due parametri (un oggetto per l'origine dell'evento e un oggetto per i dati dell'evento).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).

I delegati sono multicast, il che significa che possono mantenere riferimenti a più di un metodo di gestione degli eventi.Delegates are multicast, which means that they can hold references to more than one event-handling method. Per informazioni dettagliate, vedere la pagina di riferimento per Delegate.For details, see the Delegate reference page. I delegati offrono flessibilità e controlli specifici nella gestione degli eventi.Delegates provide flexibility and fine-grained control in event handling. Un delegato agisce come un dispatcher di eventi per la classe che genera l'evento compilando un elenco di gestori eventi registrati per l'evento.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.

Per gli scenari in cui i delegati EventHandler e EventHandler<TEventArgs> non sono appropriati, è possibile definire un delegato.For scenarios where the EventHandler and EventHandler<TEventArgs> delegates do not work, you can define a delegate. Gli scenari che richiedono di definire un delegato sono molto rari, ad esempio quando è necessario lavorare con un codice che non riconosce i generics.Scenarios that require you to define a delegate are very rare, such as when you must work with code that does not recognize generics. Nella dichiarazione, contrassegnare un delegato con la parola chiave delegate (in C#) o Delegate (in Visual Basic).You mark a delegate with the delegate in (C#) and Delegate (in Visual Basic) keyword in the declaration. Nell'esempio riportato di seguito viene illustrato come dichiarare un delegato denominato 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)

Dati eventiEvent Data

I dati associati a un evento possono essere forniti tramite una classe di dati eventi.Data that is associated with an event can be provided through an event data class. .NET Framework fornisce molte classi di dati eventi che possono essere usate nelle applicazioni.The .NET Framework provides many event data classes that you can use in your applications. Ad esempio, la classe SerialDataReceivedEventArgs è la classe di dati eventi per l'evento SerialPort.DataReceived.For example, the SerialDataReceivedEventArgs class is the event data class for the SerialPort.DataReceived event. .NET Framework segue un modello di denominazione che prevede di terminare tutte le classi di dati eventi con EventArgs.The .NET Framework follows a naming pattern of ending all event data classes with EventArgs. È possibile determinare quale classe di dati eventi è associata a un evento esaminando il delegato per tale evento.You determine which event data class is associated with an event by looking at the delegate for the event. Ad esempio, il delegato SerialDataReceivedEventHandler include la classe SerialDataReceivedEventArgs come uno dei relativi parametri.For example, the SerialDataReceivedEventHandler delegate includes the SerialDataReceivedEventArgs class as one of its parameters.

La classe EventArgs è il tipo base per tutte le classi di dati eventi.The EventArgs class is the base type for all event data classes. EventArgs è anche la classe usata quando a un evento non sono stati associati dati.EventArgs is also the class you use when an event does not have any data associated with it. Quando si crea un evento il cui solo scopo è quello di segnalare ad altre classi che si è verificato qualcosa e non è necessario passare i dati, includere la classe EventArgs come secondo parametro nel delegato.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. È possibile passare il valore EventArgs.Empty quando non viene fornito alcun dato.You can pass the EventArgs.Empty value when no data is provided. Il delegato EventHandler include la classe EventArgs come parametro.The EventHandler delegate includes the EventArgs class as a parameter.

Quando si vuole creare una classe di dati eventi personalizzata, creare una classe che deriva da EventArgs e quindi specificare i membri necessari per passare i dati correlati all'evento.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. In genere, è necessario usare lo stesso modello di denominazione di .NET Framework e terminare il nome della classe di dati eventi con EventArgs.Typically, you should use the same naming pattern as the .NET Framework and end your event data class name with EventArgs.

Nell'esempio seguente viene illustrata una classe di dati eventi denominata ThresholdReachedEventArgs.The following example shows an event data class named ThresholdReachedEventArgs. Contiene le proprietà specifiche per l'evento generato.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

Gestori eventiEvent Handlers

Per rispondere a un evento, definire un metodo del gestore eventi nel ricevitore di eventi.To respond to an event, you define an event handler method in the event receiver. Questo metodo deve corrispondere alla firma del delegato per l'evento gestito.This method must match the signature of the delegate for the event you are handling. Nel gestore eventi eseguire le azioni necessarie quando viene generato l'evento, ad esempio la raccolta dell'input quando un utente fa clic su un pulsante.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. Per ricevere notifiche quando si verifica l'evento, il metodo del gestore eventi deve sottoscrivere l'evento.To receive notifications when the event occurs, your event handler method must subscribe to the event.

Nell'esempio seguente viene illustrato un metodo del gestore eventi denominato c_ThresholdReached che corrisponde alla firma per il delegato EventHandler.The following example shows an event handler method named c_ThresholdReached that matches the signature for the EventHandler delegate. Il metodo sottoscrive l'evento ThresholdReached.The method subscribes to the ThresholdReached event.

class Program
{
    static void Main(string[] args)
    {
        Counter 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 Counter = 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

Gestori eventi statici e dinamiciStatic and Dynamic Event Handlers

.NET Framework consente ai sottoscrittori di registrarsi per le notifiche degli eventi in modo statico o dinamico.The .NET Framework allows subscribers to register for event notifications either statically or dynamically. I gestori eventi statici sono attivi per l'intera durata della classe di cui gestiscono gli eventi.Static event handlers are in effect for the entire life of the class whose events they handle. I gestori eventi dinamici sono attivati e disattivati in modo esplicito durante l'esecuzione del programma, in genere in risposta a una logica di programma condizionale.Dynamic event handlers are explicitly activated and deactivated during program execution, usually in response to some conditional program logic. Ad esempio, possono essere usati se le notifiche degli eventi sono necessarie solo in determinate condizioni oppure se un'applicazione fornisce più gestori eventi e le condizioni di runtime definiscono quello appropriato da usare.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. Nell'esempio della sezione precedente viene illustrato come aggiungere un gestore eventi in modo dinamico.The example in the previous section shows how to dynamically add an event handler. Per altre informazioni, vedere Eventi ed Eventi.For more information, see Events and Events.

Generazione di più eventiRaising Multiple Events

Se la propria classe genera più eventi, il compilatore genera un campo per ogni istanza del delegato di evento.If your class raises multiple events, the compiler generates one field per event delegate instance. Se il numero di eventi è elevato, il costo di archiviazione di un campo per ciascun delegato non è sostenibile.If the number of events is large, the storage cost of one field per delegate may not be acceptable. Per questi casi, .NET Framework fornisce le proprietà evento che è possibile usare con un'altra struttura di dati di propria scelta per archiviare i delegati degli eventi.For those situations, the .NET Framework provides event properties that you can use with another data structure of your choice to store event delegates.

Le proprietà dell'evento sono costituite da dichiarazioni di eventi accompagnate dalle funzioni di accesso agli eventi.Event properties consist of event declarations accompanied by event accessors. Queste funzioni sono metodi che consentono di aggiungere o rimuovere istanze del delegato di evento dalla struttura di dati di archiviazione.Event accessors are methods that you define to add or remove event delegate instances from the storage data structure. Si noti che le proprietà evento sono più lente rispetto ai campi evento, perché ogni delegato dell'evento deve essere recuperato prima di poter essere richiamato.Note that event properties are slower than event fields, because each event delegate must be retrieved before it can be invoked. Il compromesso è tra memoria e velocità.The trade-off is between memory and speed. Se la classe definisce molti eventi che vengono generati di rado, sarà necessario implementare le proprietà degli eventi.If your class defines many events that are infrequently raised, you will want to implement event properties. Per altre informazioni, vedere Procedura: gestire più eventi mediante le relative proprietà.For more information, see How to: Handle Multiple Events Using Event Properties.

TitoloTitle DescrizioneDescription
Procedura: generare e utilizzare eventiHow to: Raise and Consume Events Contiene esempi di generazione e uso di eventi.Contains examples of raising and consuming events.
Procedura: gestire più eventi mediante le relative proprietàHow to: Handle Multiple Events Using Event Properties Viene illustrato come usare le proprietà degli eventi per gestire più eventi.Shows how to use event properties to handle multiple events.
Modello di progettazione observerObserver Design Pattern Viene descritto lo schema progettuale che consente a un sottoscrittore di effettuare la registrazione con e ricevere notifiche da un provider.Describes the design pattern that enables a subscriber to register with, and receive notifications from, a provider.
Procedura: Usare eventi in un'applicazione Web FormHow to: Consume Events in a Web Forms Application Viene illustrato come gestire un evento generato da un controllo Web Form.Shows how to handle an event that is raised by a Web Forms control.

Vedere ancheSee Also

EventHandler
EventHandler<TEventArgs>
EventArgs
Delegate
Panoramica degli eventi e degli eventi indirizzati (app UWP)Events and routed events overview (UWP apps)
Eventi (Visual Basic)Events (Visual Basic)
Eventi (Guida per programmatori C#)Events (C# Programming Guide)