Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Gli eventi in .NET sono basati sul modello delegato. Il modello delegato segue il modello di progettazione observer, che consente a un sottoscrittore di registrarsi e ricevere notifiche da un provider. Un mittente di eventi esegue il push di una notifica quando si verifica un evento. Un ricevitore di eventi definisce la risposta. Questo articolo descrive i componenti principali del modello delegato, come utilizzare gli eventi nelle applicazioni e come implementare eventi nel codice.
Generare eventi con un generatore di eventi
Un evento è un messaggio inviato da un oggetto per segnalare l'occorrenza di un'azione. L'azione potrebbe essere un'interazione dell'utente, ad esempio la pressione di un pulsante, oppure potrebbe derivare da un'altra logica del programma, ad esempio una modifica del valore della proprietà. L'oggetto che genera l'evento viene chiamato mittente dell'evento . Il mittente dell'evento non conosce l'oggetto o il metodo che riceve (handle) gli eventi generati. 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.
Per definire un evento, usare la parola chiave C# event o Visual Basic Event nella firma della classe di evento e specificare il tipo di delegato per l'evento. I delegati sono descritti nella sezione successiva.
In genere, per generare un evento, si aggiunge un metodo contrassegnato come protected
e virtual
(in C#) o Protected
e Overridable
(in Visual Basic). La convenzione di denominazione per il metodo è On<EventName>
, ad esempio OnDataReceived
. Il metodo deve accettare un parametro che specifica un oggetto dati evento, ovvero un oggetto di tipo EventArgs o un tipo derivato. Questo metodo consente alle classi derivate di eseguire l'override della logica per generare l'evento. Una classe derivata deve sempre chiamare il metodo On<EventName>
della classe base per garantire che i delegati registrati ricevano l'evento.
Nell'esempio seguente viene illustrato come dichiarare un evento denominato ThresholdReached
. L'evento è associato al delegato EventHandler e generato in un metodo denominato 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
Dichiarare le firme dei delegati per i gestori di eventi
Un delegato è un tipo che contiene un riferimento a un metodo. Un delegato viene dichiarato con una firma che mostra il tipo di ritorno e i parametri per i metodi a cui fa riferimento. Può contenere riferimenti solo ai metodi che corrispondono alla firma. Un delegato equivale a un puntatore a funzione a tipo sicuro o a un callback. Una dichiarazione di delegato è sufficiente per definire una classe delegato.
I delegati hanno molti usi in .NET. Nel contesto degli eventi, un delegato è un meccanismo intermedio tra la sorgente dell'evento e il codice che gestisce l'evento, simile a un puntatore. È possibile associare un delegato a un evento includendo il tipo delegato nella dichiarazione di evento, come illustrato nell'esempio nella sezione precedente. Per altre informazioni sui delegati, vedere la classe Delegate.
.NET fornisce i delegati EventHandler e EventHandler<TEventArgs> per supportare la maggior parte degli scenari di eventi. Usare il delegato EventHandler per tutti gli eventi che non includono i dati dell'evento. Usare il delegato EventHandler<TEventArgs> per gli eventi che includono dati sull'evento. 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).
I delegati sono oggetti di classe multicast, ovvero possono contenere riferimenti a più metodi di gestione degli eventi. Per altre informazioni, vedere la pagina di riferimento Delegate. I delegati offrono flessibilità e controllo con granularità fine nella gestione degli eventi. Un delegato funge da dispatcher di eventi per la classe che genera l'evento mantenendo un elenco di gestori eventi registrati per l'evento.
Usare i tipi delegato EventHandler e EventHandler<TEventArgs> per definire il delegato necessario. Contrassegna un delegato con il tipo di delegate
in [C#]](../../csharp/language-reference/builtin-types/reference-types.md#the-delegate-type) o il tipo Delegate
in Visual Basic nella dichiarazione. Nell'esempio seguente viene illustrato come dichiarare un delegato denominato ThresholdReachedEventHandler
:
public delegate void ThresholdReachedEventHandler(object sender, ThresholdReachedEventArgs e);
Public Delegate Sub ThresholdReachedEventHandler(sender As Object, e As ThresholdReachedEventArgs)
Usare le classi di dati degli eventi
I dati associati a un evento possono essere forniti tramite una classe di dati di evento. .NET offre molte classi di dati di evento che è possibile usare nelle applicazioni. Ad esempio, la classe SerialDataReceivedEventArgs è la classe di dati dell'evento SerialPort.DataReceived. .NET segue un modello di denominazione in cui tutte le classi di dati degli eventi terminano con il suffisso EventArgs
. Determinare quale classe di dati dell'evento è associata a un evento osservando il delegato dell'evento. Ad esempio, il delegato SerialDataReceivedEventHandler include la classe SerialDataReceivedEventArgs come parametro.
La classe EventArgs è in genere il tipo di base per le classi di dati dell'evento. Questa classe viene usata anche se a un evento non sono associati dati. Quando si crea un evento che notifica ai sottoscrittori che si è verificato un evento senza dati aggiuntivi, includere la classe EventArgs come secondo parametro nel delegato. È possibile passare il valore EventArgs.Empty quando non vengono forniti dati. Il delegato EventHandler include la classe EventArgs come parametro.
È possibile creare una classe che deriva dalla classe EventArgs per fornire i membri necessari per passare i dati correlati all'evento. In genere, è consigliabile usare lo stesso modello di denominazione di .NET e terminare il nome della classe di dati dell'evento con il suffisso EventArgs
.
Nell'esempio seguente viene illustrata una classe di dati evento denominata ThresholdReachedEventArgs
che contiene proprietà specifiche dell'evento generato:
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
Rispondere agli eventi con gli handler
Per rispondere a un evento, definire un metodo del gestore eventi nel ricevitore di eventi. Questo metodo deve corrispondere alla firma del delegato per l'evento che si sta gestendo. Nel gestore eventi si eseguono le azioni necessarie quando viene generato l'evento, ad esempio la raccolta dell'input dell'utente dopo che l'utente preme un pulsante. Per ricevere notifiche quando si verifica l'evento, il metodo del gestore eventi deve sottoscrivere l'evento.
Nell'esempio seguente viene illustrato un metodo del gestore eventi denominato c_ThresholdReached
che corrisponde alla firma per il delegato EventHandler. Il metodo si iscrive all'evento 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
Usare gestori eventi statici e dinamici
.NET consente ai sottoscrittori di registrarsi per le notifiche degli eventi in modo statico o dinamico. I gestori eventi statici sono attivi per l'intera durata della classe i cui eventi gestiscono. I gestori eventi dinamici vengono attivati e disattivati in modo esplicito durante l'esecuzione del programma, in genere in risposta a una logica del programma condizionale. È possibile usare gestori dinamici quando le notifiche degli eventi sono necessarie solo in determinate condizioni o quando le condizioni di runtime determinano il gestore specifico da chiamare. Nell'esempio della sezione precedente viene illustrato come aggiungere dinamicamente un gestore eventi. Per altre informazioni, vedere Events (in Visual Basic) e Events (in C#).
Attivare più eventi
Se la classe genera più eventi, il compilatore genera un campo per ogni istanza del delegato di evento. Se il numero di eventi è elevato, il costo di archiviazione di un campo per delegato potrebbe non essere accettabile. Per questi scenari, .NET fornisce proprietà degli eventi che è possibile usare con un'altra struttura di dati di propria scelta per archiviare i delegati di eventi.
Le proprietà di eventi consistono in dichiarazioni di eventi accompagnate da metodi di accesso agli eventi. Le funzioni di accesso agli eventi sono metodi definiti per aggiungere o rimuovere istanze del delegato dell'evento nella struttura dati di archiviazione.
Nota
Le proprietà degli eventi sono più lente dei campi degli eventi perché ogni delegato dell'evento deve essere recuperato prima di poter essere invocato.
Il compromesso è tra memoria e velocità. Se la classe definisce molti eventi generati raramente, è necessario implementare le proprietà degli eventi. Per altre informazioni, vedere Gestire più eventi usando le proprietà degli eventi.
Esplorare le attività correlate
Le risorse seguenti descrivono altre attività e concetti relativi all'uso degli eventi:
- Generare e utilizzare eventi: trovare esempi per la generazione e l'utilizzo di eventi.
- Gestire più eventi con le proprietà degli eventi: informazioni su come usare le proprietà degli eventi per gestire più eventi.
- Esplorare il modello di progettazione osservatore: esaminare un modello di progettazione che consente a un sottoscrittore di registrarsi e ricevere notifiche da un provider.
Esaminare la specificazione di riferimento
La documentazione di riferimento sulle specifiche è disponibile per le API che supportano la gestione degli eventi:
Nome API | Tipo di API | Riferimento |
---|---|---|
EventHandler | Delegare | EventHandler |
EventHandler<TEventArgs> | Delegare | EventHandler<TEventArgs> |
EventArgs | Classe | EventArgs |
Delegare | Classe | Delegate |