This article shows how to work with events in .NET using the System.EventHandler delegate, the System.EventHandler delegate, and a custom delegate, with examples for events with and without data.
Prerequisites
Familiarize yourself with the concepts in the Events article.
Raise an event without data
These steps create a Counter class that fires a ThresholdReached event when a running total reaches or exceeds a threshold.
Declare the event using the System.EventHandler delegate.
Use
EventHandlerwhen your event doesn't pass data to the handler:
sample · csharpdocs/standard/events/snippets/how-to-raise-and-consume-events/csharp/EventNoData.csDeclareEvent
// <ThresholdReachedNoData>
class EventNoData
{
static void Main()
{
Counter c = new(new Random().Next(10));
// <SubscribeEvent>
c.ThresholdReached += c_ThresholdReached;
// </SubscribeEvent>
Console.WriteLine("press 'a' key to increase total");
while (Console.ReadKey(true).KeyChar == 'a')
{
Console.WriteLine("adding one");
c.Add(1);
}
}
// <HandleEvent>
static void c_ThresholdReached(object? sender, EventArgs e)
{
Console.WriteLine("The threshold was reached.");
Environment.Exit(0);
}
// </HandleEvent>
}
class Counter(int passedThreshold)
{
private readonly int _threshold = passedThreshold;
private int _total;
public void Add(int x)
{
_total += x;
// <RaiseEvent>
if (_total >= _threshold)
{
OnThresholdReached(EventArgs.Empty);
}
// </RaiseEvent>
}
// <RaiseEventMethod>
protected virtual void OnThresholdReached(EventArgs e)
{
ThresholdReached?.Invoke(this, e);
}
// </RaiseEventMethod>
// <DeclareEvent>
public event EventHandler? ThresholdReached;
// </DeclareEvent>
}
// </ThresholdReachedNoData>sample · vbdocs/standard/events/snippets/how-to-raise-and-consume-events/vb/EventNoData.vbDeclareEvent
' <ThresholdReachedNoData>
Module EventNoData
Sub Main()
Dim c As New Counter(New Random().Next(10))
' <SubscribeEvent>
AddHandler c.ThresholdReached, AddressOf c_ThresholdReached
' </SubscribeEvent>
Console.WriteLine("press 'a' key to increase total")
While Console.ReadKey(True).KeyChar = "a"
Console.WriteLine("adding one")
c.Add(1)
End While
End Sub
' <HandleEvent>
Sub c_ThresholdReached(sender As Object, e As EventArgs)
Console.WriteLine("The threshold was reached.")
Environment.Exit(0)
End Sub
' </HandleEvent>
End Module
Class Counter
Private ReadOnly _threshold As Integer
Private _total As Integer
Public Sub New(passedThreshold As Integer)
_threshold = passedThreshold
End Sub
Public Sub Add(x As Integer)
_total += x
' <RaiseEvent>
If (_total >= _threshold) Then
OnThresholdReached(EventArgs.Empty)
End If
' </RaiseEvent>
End Sub
' <RaiseEventMethod>
Protected Overridable Sub OnThresholdReached(e As EventArgs)
RaiseEvent ThresholdReached(Me, e)
End Sub
' </RaiseEventMethod>
' <DeclareEvent>
Public Event ThresholdReached As EventHandler
' </DeclareEvent>
End Class
' </ThresholdReachedNoData>Add a
protected virtualmethod (Protected Overridablein Visual Basic) to raise the event.This pattern lets derived classes override the event-raising behavior without directly invoking the delegate. In C#, use the null-conditional operator (
?.) to guard against no subscribers (in Visual Basic,RaiseEventhandles this automatically):
sample · csharpdocs/standard/events/snippets/how-to-raise-and-consume-events/csharp/EventNoData.csRaiseEventMethod
// <ThresholdReachedNoData>
class EventNoData
{
static void Main()
{
Counter c = new(new Random().Next(10));
// <SubscribeEvent>
c.ThresholdReached += c_ThresholdReached;
// </SubscribeEvent>
Console.WriteLine("press 'a' key to increase total");
while (Console.ReadKey(true).KeyChar == 'a')
{
Console.WriteLine("adding one");
c.Add(1);
}
}
// <HandleEvent>
static void c_ThresholdReached(object? sender, EventArgs e)
{
Console.WriteLine("The threshold was reached.");
Environment.Exit(0);
}
// </HandleEvent>
}
class Counter(int passedThreshold)
{
private readonly int _threshold = passedThreshold;
private int _total;
public void Add(int x)
{
_total += x;
// <RaiseEvent>
if (_total >= _threshold)
{
OnThresholdReached(EventArgs.Empty);
}
// </RaiseEvent>
}
// <RaiseEventMethod>
protected virtual void OnThresholdReached(EventArgs e)
{
ThresholdReached?.Invoke(this, e);
}
// </RaiseEventMethod>
// <DeclareEvent>
public event EventHandler? ThresholdReached;
// </DeclareEvent>
}
// </ThresholdReachedNoData>sample · vbdocs/standard/events/snippets/how-to-raise-and-consume-events/vb/EventNoData.vbRaiseEventMethod
' <ThresholdReachedNoData>
Module EventNoData
Sub Main()
Dim c As New Counter(New Random().Next(10))
' <SubscribeEvent>
AddHandler c.ThresholdReached, AddressOf c_ThresholdReached
' </SubscribeEvent>
Console.WriteLine("press 'a' key to increase total")
While Console.ReadKey(True).KeyChar = "a"
Console.WriteLine("adding one")
c.Add(1)
End While
End Sub
' <HandleEvent>
Sub c_ThresholdReached(sender As Object, e As EventArgs)
Console.WriteLine("The threshold was reached.")
Environment.Exit(0)
End Sub
' </HandleEvent>
End Module
Class Counter
Private ReadOnly _threshold As Integer
Private _total As Integer
Public Sub New(passedThreshold As Integer)
_threshold = passedThreshold
End Sub
Public Sub Add(x As Integer)
_total += x
' <RaiseEvent>
If (_total >= _threshold) Then
OnThresholdReached(EventArgs.Empty)
End If
' </RaiseEvent>
End Sub
' <RaiseEventMethod>
Protected Overridable Sub OnThresholdReached(e As EventArgs)
RaiseEvent ThresholdReached(Me, e)
End Sub
' </RaiseEventMethod>
' <DeclareEvent>
Public Event ThresholdReached As EventHandler
' </DeclareEvent>
End Class
' </ThresholdReachedNoData>Call the raise method when the condition is met.
Pass System.EventArgs.Empty because this event carries no data:
sample · csharpdocs/standard/events/snippets/how-to-raise-and-consume-events/csharp/EventNoData.csRaiseEvent
// <ThresholdReachedNoData>
class EventNoData
{
static void Main()
{
Counter c = new(new Random().Next(10));
// <SubscribeEvent>
c.ThresholdReached += c_ThresholdReached;
// </SubscribeEvent>
Console.WriteLine("press 'a' key to increase total");
while (Console.ReadKey(true).KeyChar == 'a')
{
Console.WriteLine("adding one");
c.Add(1);
}
}
// <HandleEvent>
static void c_ThresholdReached(object? sender, EventArgs e)
{
Console.WriteLine("The threshold was reached.");
Environment.Exit(0);
}
// </HandleEvent>
}
class Counter(int passedThreshold)
{
private readonly int _threshold = passedThreshold;
private int _total;
public void Add(int x)
{
_total += x;
// <RaiseEvent>
if (_total >= _threshold)
{
OnThresholdReached(EventArgs.Empty);
}
// </RaiseEvent>
}
// <RaiseEventMethod>
protected virtual void OnThresholdReached(EventArgs e)
{
ThresholdReached?.Invoke(this, e);
}
// </RaiseEventMethod>
// <DeclareEvent>
public event EventHandler? ThresholdReached;
// </DeclareEvent>
}
// </ThresholdReachedNoData>sample · vbdocs/standard/events/snippets/how-to-raise-and-consume-events/vb/EventNoData.vbRaiseEvent
' <ThresholdReachedNoData>
Module EventNoData
Sub Main()
Dim c As New Counter(New Random().Next(10))
' <SubscribeEvent>
AddHandler c.ThresholdReached, AddressOf c_ThresholdReached
' </SubscribeEvent>
Console.WriteLine("press 'a' key to increase total")
While Console.ReadKey(True).KeyChar = "a"
Console.WriteLine("adding one")
c.Add(1)
End While
End Sub
' <HandleEvent>
Sub c_ThresholdReached(sender As Object, e As EventArgs)
Console.WriteLine("The threshold was reached.")
Environment.Exit(0)
End Sub
' </HandleEvent>
End Module
Class Counter
Private ReadOnly _threshold As Integer
Private _total As Integer
Public Sub New(passedThreshold As Integer)
_threshold = passedThreshold
End Sub
Public Sub Add(x As Integer)
_total += x
' <RaiseEvent>
If (_total >= _threshold) Then
OnThresholdReached(EventArgs.Empty)
End If
' </RaiseEvent>
End Sub
' <RaiseEventMethod>
Protected Overridable Sub OnThresholdReached(e As EventArgs)
RaiseEvent ThresholdReached(Me, e)
End Sub
' </RaiseEventMethod>
' <DeclareEvent>
Public Event ThresholdReached As EventHandler
' </DeclareEvent>
End Class
' </ThresholdReachedNoData>- Subscribe to the event using the
+=operator (in Visual Basic,AddHandler):
sample · csharpdocs/standard/events/snippets/how-to-raise-and-consume-events/csharp/EventNoData.csSubscribeEvent
// <ThresholdReachedNoData>
class EventNoData
{
static void Main()
{
Counter c = new(new Random().Next(10));
// <SubscribeEvent>
c.ThresholdReached += c_ThresholdReached;
// </SubscribeEvent>
Console.WriteLine("press 'a' key to increase total");
while (Console.ReadKey(true).KeyChar == 'a')
{
Console.WriteLine("adding one");
c.Add(1);
}
}
// <HandleEvent>
static void c_ThresholdReached(object? sender, EventArgs e)
{
Console.WriteLine("The threshold was reached.");
Environment.Exit(0);
}
// </HandleEvent>
}
class Counter(int passedThreshold)
{
private readonly int _threshold = passedThreshold;
private int _total;
public void Add(int x)
{
_total += x;
// <RaiseEvent>
if (_total >= _threshold)
{
OnThresholdReached(EventArgs.Empty);
}
// </RaiseEvent>
}
// <RaiseEventMethod>
protected virtual void OnThresholdReached(EventArgs e)
{
ThresholdReached?.Invoke(this, e);
}
// </RaiseEventMethod>
// <DeclareEvent>
public event EventHandler? ThresholdReached;
// </DeclareEvent>
}
// </ThresholdReachedNoData>sample · vbdocs/standard/events/snippets/how-to-raise-and-consume-events/vb/EventNoData.vbSubscribeEvent
' <ThresholdReachedNoData>
Module EventNoData
Sub Main()
Dim c As New Counter(New Random().Next(10))
' <SubscribeEvent>
AddHandler c.ThresholdReached, AddressOf c_ThresholdReached
' </SubscribeEvent>
Console.WriteLine("press 'a' key to increase total")
While Console.ReadKey(True).KeyChar = "a"
Console.WriteLine("adding one")
c.Add(1)
End While
End Sub
' <HandleEvent>
Sub c_ThresholdReached(sender As Object, e As EventArgs)
Console.WriteLine("The threshold was reached.")
Environment.Exit(0)
End Sub
' </HandleEvent>
End Module
Class Counter
Private ReadOnly _threshold As Integer
Private _total As Integer
Public Sub New(passedThreshold As Integer)
_threshold = passedThreshold
End Sub
Public Sub Add(x As Integer)
_total += x
' <RaiseEvent>
If (_total >= _threshold) Then
OnThresholdReached(EventArgs.Empty)
End If
' </RaiseEvent>
End Sub
' <RaiseEventMethod>
Protected Overridable Sub OnThresholdReached(e As EventArgs)
RaiseEvent ThresholdReached(Me, e)
End Sub
' </RaiseEventMethod>
' <DeclareEvent>
Public Event ThresholdReached As EventHandler
' </DeclareEvent>
End Class
' </ThresholdReachedNoData>Define the event handler method.
Its signature must match the System.EventHandler delegate—the first parameter is the event source and the second is System.EventArgs:
sample · csharpdocs/standard/events/snippets/how-to-raise-and-consume-events/csharp/EventNoData.csHandleEvent
// <ThresholdReachedNoData>
class EventNoData
{
static void Main()
{
Counter c = new(new Random().Next(10));
// <SubscribeEvent>
c.ThresholdReached += c_ThresholdReached;
// </SubscribeEvent>
Console.WriteLine("press 'a' key to increase total");
while (Console.ReadKey(true).KeyChar == 'a')
{
Console.WriteLine("adding one");
c.Add(1);
}
}
// <HandleEvent>
static void c_ThresholdReached(object? sender, EventArgs e)
{
Console.WriteLine("The threshold was reached.");
Environment.Exit(0);
}
// </HandleEvent>
}
class Counter(int passedThreshold)
{
private readonly int _threshold = passedThreshold;
private int _total;
public void Add(int x)
{
_total += x;
// <RaiseEvent>
if (_total >= _threshold)
{
OnThresholdReached(EventArgs.Empty);
}
// </RaiseEvent>
}
// <RaiseEventMethod>
protected virtual void OnThresholdReached(EventArgs e)
{
ThresholdReached?.Invoke(this, e);
}
// </RaiseEventMethod>
// <DeclareEvent>
public event EventHandler? ThresholdReached;
// </DeclareEvent>
}
// </ThresholdReachedNoData>sample · vbdocs/standard/events/snippets/how-to-raise-and-consume-events/vb/EventNoData.vbHandleEvent
' <ThresholdReachedNoData>
Module EventNoData
Sub Main()
Dim c As New Counter(New Random().Next(10))
' <SubscribeEvent>
AddHandler c.ThresholdReached, AddressOf c_ThresholdReached
' </SubscribeEvent>
Console.WriteLine("press 'a' key to increase total")
While Console.ReadKey(True).KeyChar = "a"
Console.WriteLine("adding one")
c.Add(1)
End While
End Sub
' <HandleEvent>
Sub c_ThresholdReached(sender As Object, e As EventArgs)
Console.WriteLine("The threshold was reached.")
Environment.Exit(0)
End Sub
' </HandleEvent>
End Module
Class Counter
Private ReadOnly _threshold As Integer
Private _total As Integer
Public Sub New(passedThreshold As Integer)
_threshold = passedThreshold
End Sub
Public Sub Add(x As Integer)
_total += x
' <RaiseEvent>
If (_total >= _threshold) Then
OnThresholdReached(EventArgs.Empty)
End If
' </RaiseEvent>
End Sub
' <RaiseEventMethod>
Protected Overridable Sub OnThresholdReached(e As EventArgs)
RaiseEvent ThresholdReached(Me, e)
End Sub
' </RaiseEventMethod>
' <DeclareEvent>
Public Event ThresholdReached As EventHandler
' </DeclareEvent>
End Class
' </ThresholdReachedNoData>The following example shows the complete implementation:
sample · csharpdocs/standard/events/snippets/how-to-raise-and-consume-events/csharp/EventNoData.csThresholdReachedNoData
// <ThresholdReachedNoData>
class EventNoData
{
static void Main()
{
Counter c = new(new Random().Next(10));
// <SubscribeEvent>
c.ThresholdReached += c_ThresholdReached;
// </SubscribeEvent>
Console.WriteLine("press 'a' key to increase total");
while (Console.ReadKey(true).KeyChar == 'a')
{
Console.WriteLine("adding one");
c.Add(1);
}
}
// <HandleEvent>
static void c_ThresholdReached(object? sender, EventArgs e)
{
Console.WriteLine("The threshold was reached.");
Environment.Exit(0);
}
// </HandleEvent>
}
class Counter(int passedThreshold)
{
private readonly int _threshold = passedThreshold;
private int _total;
public void Add(int x)
{
_total += x;
// <RaiseEvent>
if (_total >= _threshold)
{
OnThresholdReached(EventArgs.Empty);
}
// </RaiseEvent>
}
// <RaiseEventMethod>
protected virtual void OnThresholdReached(EventArgs e)
{
ThresholdReached?.Invoke(this, e);
}
// </RaiseEventMethod>
// <DeclareEvent>
public event EventHandler? ThresholdReached;
// </DeclareEvent>
}
// </ThresholdReachedNoData>sample · vbdocs/standard/events/snippets/how-to-raise-and-consume-events/vb/EventNoData.vbThresholdReachedNoData
' <ThresholdReachedNoData>
Module EventNoData
Sub Main()
Dim c As New Counter(New Random().Next(10))
' <SubscribeEvent>
AddHandler c.ThresholdReached, AddressOf c_ThresholdReached
' </SubscribeEvent>
Console.WriteLine("press 'a' key to increase total")
While Console.ReadKey(True).KeyChar = "a"
Console.WriteLine("adding one")
c.Add(1)
End While
End Sub
' <HandleEvent>
Sub c_ThresholdReached(sender As Object, e As EventArgs)
Console.WriteLine("The threshold was reached.")
Environment.Exit(0)
End Sub
' </HandleEvent>
End Module
Class Counter
Private ReadOnly _threshold As Integer
Private _total As Integer
Public Sub New(passedThreshold As Integer)
_threshold = passedThreshold
End Sub
Public Sub Add(x As Integer)
_total += x
' <RaiseEvent>
If (_total >= _threshold) Then
OnThresholdReached(EventArgs.Empty)
End If
' </RaiseEvent>
End Sub
' <RaiseEventMethod>
Protected Overridable Sub OnThresholdReached(e As EventArgs)
RaiseEvent ThresholdReached(Me, e)
End Sub
' </RaiseEventMethod>
' <DeclareEvent>
Public Event ThresholdReached As EventHandler
' </DeclareEvent>
End Class
' </ThresholdReachedNoData>Raise an event with data
These steps extend the previous Counter example to raise an event that includes data—the threshold value and the time it was reached.
Define an event data class that inherits from System.EventArgs.
Add properties for each piece of data you want to pass to the handler:
sample · csharpdocs/standard/events/snippets/how-to-raise-and-consume-events/csharp/EventWithData.csEventDataClass2
// <ThresholdReachedWithData>
class EventWithData
{
static void Main()
{
CounterWithData c = new(new Random().Next(10));
// <SubscribeEvent2>
c.ThresholdReached += c_ThresholdReached;
// </SubscribeEvent2>
Console.WriteLine("press 'a' key to increase total");
while (Console.ReadKey(true).KeyChar == 'a')
{
Console.WriteLine("adding one");
c.Add(1);
}
}
// <HandleEvent2>
static void c_ThresholdReached(object? sender, ThresholdReachedEventArgs e)
{
Console.WriteLine($"The threshold of {e.Threshold} was reached at {e.TimeReached}.");
Environment.Exit(0);
}
// </HandleEvent2>
}
class CounterWithData(int passedThreshold)
{
private readonly int _threshold = passedThreshold;
private int _total;
public void Add(int x)
{
_total += x;
// <RaiseEvent2>
if (_total >= _threshold)
{
ThresholdReachedEventArgs args = new ThresholdReachedEventArgs();
args.Threshold = _threshold;
args.TimeReached = DateTime.Now;
OnThresholdReached(args);
}
// </RaiseEvent2>
}
// <RaiseEventMethod2>
protected virtual void OnThresholdReached(ThresholdReachedEventArgs e)
{
ThresholdReached?.Invoke(this, e);
}
// </RaiseEventMethod2>
// <DeclareEvent2>
public event EventHandler<ThresholdReachedEventArgs>? ThresholdReached;
// </DeclareEvent2>
}
// <EventDataClass2>
public class ThresholdReachedEventArgs : EventArgs
{
public int Threshold { get; set; }
public DateTime TimeReached { get; set; }
}
// </EventDataClass2>
// </ThresholdReachedWithData>sample · vbdocs/standard/events/snippets/how-to-raise-and-consume-events/vb/EventWithData.vbEventDataClass2
' <ThresholdReachedWithData>
Module EventWithData
Sub Main()
Dim c As New CounterWithData(New Random().Next(10))
' <SubscribeEvent2>
AddHandler c.ThresholdReached, AddressOf c_ThresholdReached
' </SubscribeEvent2>
Console.WriteLine("press 'a' key to increase total")
While Console.ReadKey(True).KeyChar = "a"
Console.WriteLine("adding one")
c.Add(1)
End While
End Sub
' <HandleEvent2>
Sub c_ThresholdReached(sender As Object, e As ThresholdReachedEventArgs)
Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold, e.TimeReached)
Environment.Exit(0)
End Sub
' </HandleEvent2>
End Module
Class CounterWithData
Private ReadOnly _threshold As Integer
Private _total As Integer
Public Sub New(passedThreshold As Integer)
_threshold = passedThreshold
End Sub
Public Sub Add(x As Integer)
_total += x
' <RaiseEvent2>
If (_total >= _threshold) Then
Dim args As New ThresholdReachedEventArgs With {
.Threshold = _threshold,
.TimeReached = Date.Now
}
OnThresholdReached(args)
End If
' </RaiseEvent2>
End Sub
' <RaiseEventMethod2>
Protected Overridable Sub OnThresholdReached(e As ThresholdReachedEventArgs)
RaiseEvent ThresholdReached(Me, e)
End Sub
' </RaiseEventMethod2>
' <DeclareEvent2>
Public Event ThresholdReached As EventHandler(Of ThresholdReachedEventArgs)
' </DeclareEvent2>
End Class
' <EventDataClass2>
Class ThresholdReachedEventArgs
Inherits EventArgs
Public Property Threshold As Integer
Public Property TimeReached As Date
End Class
' </EventDataClass2>
' </ThresholdReachedWithData>- Declare the event using the System.EventHandler delegate, passing your event data class as the type argument:
sample · csharpdocs/standard/events/snippets/how-to-raise-and-consume-events/csharp/EventWithData.csDeclareEvent2
// <ThresholdReachedWithData>
class EventWithData
{
static void Main()
{
CounterWithData c = new(new Random().Next(10));
// <SubscribeEvent2>
c.ThresholdReached += c_ThresholdReached;
// </SubscribeEvent2>
Console.WriteLine("press 'a' key to increase total");
while (Console.ReadKey(true).KeyChar == 'a')
{
Console.WriteLine("adding one");
c.Add(1);
}
}
// <HandleEvent2>
static void c_ThresholdReached(object? sender, ThresholdReachedEventArgs e)
{
Console.WriteLine($"The threshold of {e.Threshold} was reached at {e.TimeReached}.");
Environment.Exit(0);
}
// </HandleEvent2>
}
class CounterWithData(int passedThreshold)
{
private readonly int _threshold = passedThreshold;
private int _total;
public void Add(int x)
{
_total += x;
// <RaiseEvent2>
if (_total >= _threshold)
{
ThresholdReachedEventArgs args = new ThresholdReachedEventArgs();
args.Threshold = _threshold;
args.TimeReached = DateTime.Now;
OnThresholdReached(args);
}
// </RaiseEvent2>
}
// <RaiseEventMethod2>
protected virtual void OnThresholdReached(ThresholdReachedEventArgs e)
{
ThresholdReached?.Invoke(this, e);
}
// </RaiseEventMethod2>
// <DeclareEvent2>
public event EventHandler<ThresholdReachedEventArgs>? ThresholdReached;
// </DeclareEvent2>
}
// <EventDataClass2>
public class ThresholdReachedEventArgs : EventArgs
{
public int Threshold { get; set; }
public DateTime TimeReached { get; set; }
}
// </EventDataClass2>
// </ThresholdReachedWithData>sample · vbdocs/standard/events/snippets/how-to-raise-and-consume-events/vb/EventWithData.vbDeclareEvent2
' <ThresholdReachedWithData>
Module EventWithData
Sub Main()
Dim c As New CounterWithData(New Random().Next(10))
' <SubscribeEvent2>
AddHandler c.ThresholdReached, AddressOf c_ThresholdReached
' </SubscribeEvent2>
Console.WriteLine("press 'a' key to increase total")
While Console.ReadKey(True).KeyChar = "a"
Console.WriteLine("adding one")
c.Add(1)
End While
End Sub
' <HandleEvent2>
Sub c_ThresholdReached(sender As Object, e As ThresholdReachedEventArgs)
Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold, e.TimeReached)
Environment.Exit(0)
End Sub
' </HandleEvent2>
End Module
Class CounterWithData
Private ReadOnly _threshold As Integer
Private _total As Integer
Public Sub New(passedThreshold As Integer)
_threshold = passedThreshold
End Sub
Public Sub Add(x As Integer)
_total += x
' <RaiseEvent2>
If (_total >= _threshold) Then
Dim args As New ThresholdReachedEventArgs With {
.Threshold = _threshold,
.TimeReached = Date.Now
}
OnThresholdReached(args)
End If
' </RaiseEvent2>
End Sub
' <RaiseEventMethod2>
Protected Overridable Sub OnThresholdReached(e As ThresholdReachedEventArgs)
RaiseEvent ThresholdReached(Me, e)
End Sub
' </RaiseEventMethod2>
' <DeclareEvent2>
Public Event ThresholdReached As EventHandler(Of ThresholdReachedEventArgs)
' </DeclareEvent2>
End Class
' <EventDataClass2>
Class ThresholdReachedEventArgs
Inherits EventArgs
Public Property Threshold As Integer
Public Property TimeReached As Date
End Class
' </EventDataClass2>
' </ThresholdReachedWithData>Add a
protected virtualmethod (Protected Overridablein Visual Basic) to raise the event.This pattern lets derived classes override the event-raising behavior without directly invoking the delegate. In C#, use the null-conditional operator (
?.) to guard against no subscribers (in Visual Basic,RaiseEventhandles this automatically):
sample · csharpdocs/standard/events/snippets/how-to-raise-and-consume-events/csharp/EventWithData.csRaiseEventMethod2
// <ThresholdReachedWithData>
class EventWithData
{
static void Main()
{
CounterWithData c = new(new Random().Next(10));
// <SubscribeEvent2>
c.ThresholdReached += c_ThresholdReached;
// </SubscribeEvent2>
Console.WriteLine("press 'a' key to increase total");
while (Console.ReadKey(true).KeyChar == 'a')
{
Console.WriteLine("adding one");
c.Add(1);
}
}
// <HandleEvent2>
static void c_ThresholdReached(object? sender, ThresholdReachedEventArgs e)
{
Console.WriteLine($"The threshold of {e.Threshold} was reached at {e.TimeReached}.");
Environment.Exit(0);
}
// </HandleEvent2>
}
class CounterWithData(int passedThreshold)
{
private readonly int _threshold = passedThreshold;
private int _total;
public void Add(int x)
{
_total += x;
// <RaiseEvent2>
if (_total >= _threshold)
{
ThresholdReachedEventArgs args = new ThresholdReachedEventArgs();
args.Threshold = _threshold;
args.TimeReached = DateTime.Now;
OnThresholdReached(args);
}
// </RaiseEvent2>
}
// <RaiseEventMethod2>
protected virtual void OnThresholdReached(ThresholdReachedEventArgs e)
{
ThresholdReached?.Invoke(this, e);
}
// </RaiseEventMethod2>
// <DeclareEvent2>
public event EventHandler<ThresholdReachedEventArgs>? ThresholdReached;
// </DeclareEvent2>
}
// <EventDataClass2>
public class ThresholdReachedEventArgs : EventArgs
{
public int Threshold { get; set; }
public DateTime TimeReached { get; set; }
}
// </EventDataClass2>
// </ThresholdReachedWithData>sample · vbdocs/standard/events/snippets/how-to-raise-and-consume-events/vb/EventWithData.vbRaiseEventMethod2
' <ThresholdReachedWithData>
Module EventWithData
Sub Main()
Dim c As New CounterWithData(New Random().Next(10))
' <SubscribeEvent2>
AddHandler c.ThresholdReached, AddressOf c_ThresholdReached
' </SubscribeEvent2>
Console.WriteLine("press 'a' key to increase total")
While Console.ReadKey(True).KeyChar = "a"
Console.WriteLine("adding one")
c.Add(1)
End While
End Sub
' <HandleEvent2>
Sub c_ThresholdReached(sender As Object, e As ThresholdReachedEventArgs)
Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold, e.TimeReached)
Environment.Exit(0)
End Sub
' </HandleEvent2>
End Module
Class CounterWithData
Private ReadOnly _threshold As Integer
Private _total As Integer
Public Sub New(passedThreshold As Integer)
_threshold = passedThreshold
End Sub
Public Sub Add(x As Integer)
_total += x
' <RaiseEvent2>
If (_total >= _threshold) Then
Dim args As New ThresholdReachedEventArgs With {
.Threshold = _threshold,
.TimeReached = Date.Now
}
OnThresholdReached(args)
End If
' </RaiseEvent2>
End Sub
' <RaiseEventMethod2>
Protected Overridable Sub OnThresholdReached(e As ThresholdReachedEventArgs)
RaiseEvent ThresholdReached(Me, e)
End Sub
' </RaiseEventMethod2>
' <DeclareEvent2>
Public Event ThresholdReached As EventHandler(Of ThresholdReachedEventArgs)
' </DeclareEvent2>
End Class
' <EventDataClass2>
Class ThresholdReachedEventArgs
Inherits EventArgs
Public Property Threshold As Integer
Public Property TimeReached As Date
End Class
' </EventDataClass2>
' </ThresholdReachedWithData>- Populate the event data object and call the raise method when the condition is met:
sample · csharpdocs/standard/events/snippets/how-to-raise-and-consume-events/csharp/EventWithData.csRaiseEvent2
// <ThresholdReachedWithData>
class EventWithData
{
static void Main()
{
CounterWithData c = new(new Random().Next(10));
// <SubscribeEvent2>
c.ThresholdReached += c_ThresholdReached;
// </SubscribeEvent2>
Console.WriteLine("press 'a' key to increase total");
while (Console.ReadKey(true).KeyChar == 'a')
{
Console.WriteLine("adding one");
c.Add(1);
}
}
// <HandleEvent2>
static void c_ThresholdReached(object? sender, ThresholdReachedEventArgs e)
{
Console.WriteLine($"The threshold of {e.Threshold} was reached at {e.TimeReached}.");
Environment.Exit(0);
}
// </HandleEvent2>
}
class CounterWithData(int passedThreshold)
{
private readonly int _threshold = passedThreshold;
private int _total;
public void Add(int x)
{
_total += x;
// <RaiseEvent2>
if (_total >= _threshold)
{
ThresholdReachedEventArgs args = new ThresholdReachedEventArgs();
args.Threshold = _threshold;
args.TimeReached = DateTime.Now;
OnThresholdReached(args);
}
// </RaiseEvent2>
}
// <RaiseEventMethod2>
protected virtual void OnThresholdReached(ThresholdReachedEventArgs e)
{
ThresholdReached?.Invoke(this, e);
}
// </RaiseEventMethod2>
// <DeclareEvent2>
public event EventHandler<ThresholdReachedEventArgs>? ThresholdReached;
// </DeclareEvent2>
}
// <EventDataClass2>
public class ThresholdReachedEventArgs : EventArgs
{
public int Threshold { get; set; }
public DateTime TimeReached { get; set; }
}
// </EventDataClass2>
// </ThresholdReachedWithData>sample · vbdocs/standard/events/snippets/how-to-raise-and-consume-events/vb/EventWithData.vbRaiseEvent2
' <ThresholdReachedWithData>
Module EventWithData
Sub Main()
Dim c As New CounterWithData(New Random().Next(10))
' <SubscribeEvent2>
AddHandler c.ThresholdReached, AddressOf c_ThresholdReached
' </SubscribeEvent2>
Console.WriteLine("press 'a' key to increase total")
While Console.ReadKey(True).KeyChar = "a"
Console.WriteLine("adding one")
c.Add(1)
End While
End Sub
' <HandleEvent2>
Sub c_ThresholdReached(sender As Object, e As ThresholdReachedEventArgs)
Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold, e.TimeReached)
Environment.Exit(0)
End Sub
' </HandleEvent2>
End Module
Class CounterWithData
Private ReadOnly _threshold As Integer
Private _total As Integer
Public Sub New(passedThreshold As Integer)
_threshold = passedThreshold
End Sub
Public Sub Add(x As Integer)
_total += x
' <RaiseEvent2>
If (_total >= _threshold) Then
Dim args As New ThresholdReachedEventArgs With {
.Threshold = _threshold,
.TimeReached = Date.Now
}
OnThresholdReached(args)
End If
' </RaiseEvent2>
End Sub
' <RaiseEventMethod2>
Protected Overridable Sub OnThresholdReached(e As ThresholdReachedEventArgs)
RaiseEvent ThresholdReached(Me, e)
End Sub
' </RaiseEventMethod2>
' <DeclareEvent2>
Public Event ThresholdReached As EventHandler(Of ThresholdReachedEventArgs)
' </DeclareEvent2>
End Class
' <EventDataClass2>
Class ThresholdReachedEventArgs
Inherits EventArgs
Public Property Threshold As Integer
Public Property TimeReached As Date
End Class
' </EventDataClass2>
' </ThresholdReachedWithData>- Subscribe to the event using the
+=operator (in Visual Basic,AddHandler):
sample · csharpdocs/standard/events/snippets/how-to-raise-and-consume-events/csharp/EventWithData.csSubscribeEvent2
// <ThresholdReachedWithData>
class EventWithData
{
static void Main()
{
CounterWithData c = new(new Random().Next(10));
// <SubscribeEvent2>
c.ThresholdReached += c_ThresholdReached;
// </SubscribeEvent2>
Console.WriteLine("press 'a' key to increase total");
while (Console.ReadKey(true).KeyChar == 'a')
{
Console.WriteLine("adding one");
c.Add(1);
}
}
// <HandleEvent2>
static void c_ThresholdReached(object? sender, ThresholdReachedEventArgs e)
{
Console.WriteLine($"The threshold of {e.Threshold} was reached at {e.TimeReached}.");
Environment.Exit(0);
}
// </HandleEvent2>
}
class CounterWithData(int passedThreshold)
{
private readonly int _threshold = passedThreshold;
private int _total;
public void Add(int x)
{
_total += x;
// <RaiseEvent2>
if (_total >= _threshold)
{
ThresholdReachedEventArgs args = new ThresholdReachedEventArgs();
args.Threshold = _threshold;
args.TimeReached = DateTime.Now;
OnThresholdReached(args);
}
// </RaiseEvent2>
}
// <RaiseEventMethod2>
protected virtual void OnThresholdReached(ThresholdReachedEventArgs e)
{
ThresholdReached?.Invoke(this, e);
}
// </RaiseEventMethod2>
// <DeclareEvent2>
public event EventHandler<ThresholdReachedEventArgs>? ThresholdReached;
// </DeclareEvent2>
}
// <EventDataClass2>
public class ThresholdReachedEventArgs : EventArgs
{
public int Threshold { get; set; }
public DateTime TimeReached { get; set; }
}
// </EventDataClass2>
// </ThresholdReachedWithData>sample · vbdocs/standard/events/snippets/how-to-raise-and-consume-events/vb/EventWithData.vbSubscribeEvent2
' <ThresholdReachedWithData>
Module EventWithData
Sub Main()
Dim c As New CounterWithData(New Random().Next(10))
' <SubscribeEvent2>
AddHandler c.ThresholdReached, AddressOf c_ThresholdReached
' </SubscribeEvent2>
Console.WriteLine("press 'a' key to increase total")
While Console.ReadKey(True).KeyChar = "a"
Console.WriteLine("adding one")
c.Add(1)
End While
End Sub
' <HandleEvent2>
Sub c_ThresholdReached(sender As Object, e As ThresholdReachedEventArgs)
Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold, e.TimeReached)
Environment.Exit(0)
End Sub
' </HandleEvent2>
End Module
Class CounterWithData
Private ReadOnly _threshold As Integer
Private _total As Integer
Public Sub New(passedThreshold As Integer)
_threshold = passedThreshold
End Sub
Public Sub Add(x As Integer)
_total += x
' <RaiseEvent2>
If (_total >= _threshold) Then
Dim args As New ThresholdReachedEventArgs With {
.Threshold = _threshold,
.TimeReached = Date.Now
}
OnThresholdReached(args)
End If
' </RaiseEvent2>
End Sub
' <RaiseEventMethod2>
Protected Overridable Sub OnThresholdReached(e As ThresholdReachedEventArgs)
RaiseEvent ThresholdReached(Me, e)
End Sub
' </RaiseEventMethod2>
' <DeclareEvent2>
Public Event ThresholdReached As EventHandler(Of ThresholdReachedEventArgs)
' </DeclareEvent2>
End Class
' <EventDataClass2>
Class ThresholdReachedEventArgs
Inherits EventArgs
Public Property Threshold As Integer
Public Property TimeReached As Date
End Class
' </EventDataClass2>
' </ThresholdReachedWithData>Define the event handler.
The second parameter type is
ThresholdReachedEventArgsinstead of System.EventArgs, which lets the handler read the event data:
sample · csharpdocs/standard/events/snippets/how-to-raise-and-consume-events/csharp/EventWithData.csHandleEvent2
// <ThresholdReachedWithData>
class EventWithData
{
static void Main()
{
CounterWithData c = new(new Random().Next(10));
// <SubscribeEvent2>
c.ThresholdReached += c_ThresholdReached;
// </SubscribeEvent2>
Console.WriteLine("press 'a' key to increase total");
while (Console.ReadKey(true).KeyChar == 'a')
{
Console.WriteLine("adding one");
c.Add(1);
}
}
// <HandleEvent2>
static void c_ThresholdReached(object? sender, ThresholdReachedEventArgs e)
{
Console.WriteLine($"The threshold of {e.Threshold} was reached at {e.TimeReached}.");
Environment.Exit(0);
}
// </HandleEvent2>
}
class CounterWithData(int passedThreshold)
{
private readonly int _threshold = passedThreshold;
private int _total;
public void Add(int x)
{
_total += x;
// <RaiseEvent2>
if (_total >= _threshold)
{
ThresholdReachedEventArgs args = new ThresholdReachedEventArgs();
args.Threshold = _threshold;
args.TimeReached = DateTime.Now;
OnThresholdReached(args);
}
// </RaiseEvent2>
}
// <RaiseEventMethod2>
protected virtual void OnThresholdReached(ThresholdReachedEventArgs e)
{
ThresholdReached?.Invoke(this, e);
}
// </RaiseEventMethod2>
// <DeclareEvent2>
public event EventHandler<ThresholdReachedEventArgs>? ThresholdReached;
// </DeclareEvent2>
}
// <EventDataClass2>
public class ThresholdReachedEventArgs : EventArgs
{
public int Threshold { get; set; }
public DateTime TimeReached { get; set; }
}
// </EventDataClass2>
// </ThresholdReachedWithData>sample · vbdocs/standard/events/snippets/how-to-raise-and-consume-events/vb/EventWithData.vbHandleEvent2
' <ThresholdReachedWithData>
Module EventWithData
Sub Main()
Dim c As New CounterWithData(New Random().Next(10))
' <SubscribeEvent2>
AddHandler c.ThresholdReached, AddressOf c_ThresholdReached
' </SubscribeEvent2>
Console.WriteLine("press 'a' key to increase total")
While Console.ReadKey(True).KeyChar = "a"
Console.WriteLine("adding one")
c.Add(1)
End While
End Sub
' <HandleEvent2>
Sub c_ThresholdReached(sender As Object, e As ThresholdReachedEventArgs)
Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold, e.TimeReached)
Environment.Exit(0)
End Sub
' </HandleEvent2>
End Module
Class CounterWithData
Private ReadOnly _threshold As Integer
Private _total As Integer
Public Sub New(passedThreshold As Integer)
_threshold = passedThreshold
End Sub
Public Sub Add(x As Integer)
_total += x
' <RaiseEvent2>
If (_total >= _threshold) Then
Dim args As New ThresholdReachedEventArgs With {
.Threshold = _threshold,
.TimeReached = Date.Now
}
OnThresholdReached(args)
End If
' </RaiseEvent2>
End Sub
' <RaiseEventMethod2>
Protected Overridable Sub OnThresholdReached(e As ThresholdReachedEventArgs)
RaiseEvent ThresholdReached(Me, e)
End Sub
' </RaiseEventMethod2>
' <DeclareEvent2>
Public Event ThresholdReached As EventHandler(Of ThresholdReachedEventArgs)
' </DeclareEvent2>
End Class
' <EventDataClass2>
Class ThresholdReachedEventArgs
Inherits EventArgs
Public Property Threshold As Integer
Public Property TimeReached As Date
End Class
' </EventDataClass2>
' </ThresholdReachedWithData>The following example shows the complete implementation:
sample · csharpdocs/standard/events/snippets/how-to-raise-and-consume-events/csharp/EventWithData.csThresholdReachedWithData
// <ThresholdReachedWithData>
class EventWithData
{
static void Main()
{
CounterWithData c = new(new Random().Next(10));
// <SubscribeEvent2>
c.ThresholdReached += c_ThresholdReached;
// </SubscribeEvent2>
Console.WriteLine("press 'a' key to increase total");
while (Console.ReadKey(true).KeyChar == 'a')
{
Console.WriteLine("adding one");
c.Add(1);
}
}
// <HandleEvent2>
static void c_ThresholdReached(object? sender, ThresholdReachedEventArgs e)
{
Console.WriteLine($"The threshold of {e.Threshold} was reached at {e.TimeReached}.");
Environment.Exit(0);
}
// </HandleEvent2>
}
class CounterWithData(int passedThreshold)
{
private readonly int _threshold = passedThreshold;
private int _total;
public void Add(int x)
{
_total += x;
// <RaiseEvent2>
if (_total >= _threshold)
{
ThresholdReachedEventArgs args = new ThresholdReachedEventArgs();
args.Threshold = _threshold;
args.TimeReached = DateTime.Now;
OnThresholdReached(args);
}
// </RaiseEvent2>
}
// <RaiseEventMethod2>
protected virtual void OnThresholdReached(ThresholdReachedEventArgs e)
{
ThresholdReached?.Invoke(this, e);
}
// </RaiseEventMethod2>
// <DeclareEvent2>
public event EventHandler<ThresholdReachedEventArgs>? ThresholdReached;
// </DeclareEvent2>
}
// <EventDataClass2>
public class ThresholdReachedEventArgs : EventArgs
{
public int Threshold { get; set; }
public DateTime TimeReached { get; set; }
}
// </EventDataClass2>
// </ThresholdReachedWithData>sample · vbdocs/standard/events/snippets/how-to-raise-and-consume-events/vb/EventWithData.vbThresholdReachedWithData
' <ThresholdReachedWithData>
Module EventWithData
Sub Main()
Dim c As New CounterWithData(New Random().Next(10))
' <SubscribeEvent2>
AddHandler c.ThresholdReached, AddressOf c_ThresholdReached
' </SubscribeEvent2>
Console.WriteLine("press 'a' key to increase total")
While Console.ReadKey(True).KeyChar = "a"
Console.WriteLine("adding one")
c.Add(1)
End While
End Sub
' <HandleEvent2>
Sub c_ThresholdReached(sender As Object, e As ThresholdReachedEventArgs)
Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold, e.TimeReached)
Environment.Exit(0)
End Sub
' </HandleEvent2>
End Module
Class CounterWithData
Private ReadOnly _threshold As Integer
Private _total As Integer
Public Sub New(passedThreshold As Integer)
_threshold = passedThreshold
End Sub
Public Sub Add(x As Integer)
_total += x
' <RaiseEvent2>
If (_total >= _threshold) Then
Dim args As New ThresholdReachedEventArgs With {
.Threshold = _threshold,
.TimeReached = Date.Now
}
OnThresholdReached(args)
End If
' </RaiseEvent2>
End Sub
' <RaiseEventMethod2>
Protected Overridable Sub OnThresholdReached(e As ThresholdReachedEventArgs)
RaiseEvent ThresholdReached(Me, e)
End Sub
' </RaiseEventMethod2>
' <DeclareEvent2>
Public Event ThresholdReached As EventHandler(Of ThresholdReachedEventArgs)
' </DeclareEvent2>
End Class
' <EventDataClass2>
Class ThresholdReachedEventArgs
Inherits EventArgs
Public Property Threshold As Integer
Public Property TimeReached As Date
End Class
' </EventDataClass2>
' </ThresholdReachedWithData>Declare a custom delegate for an event
Declare a custom delegate only in rare scenarios, such as making your class available to legacy code that can't use generics. For most cases, use System.EventHandler as shown in the previous section.
Declare the custom delegate type.
The delegate signature must match the event handler signature—two parameters: the event source (
object; in Visual Basic,Object) and the event data class:
sample · csharpdocs/standard/events/snippets/how-to-raise-and-consume-events/csharp/EventWithDelegate.csDeclareDelegateType
// <ThresholdReachedWithDelegate>
class EventWithDelegate
{
static void Main()
{
CounterWithDelegate c = new(new Random().Next(10));
// <SubscribeEventDelegate>
c.ThresholdReached += c_ThresholdReached;
// </SubscribeEventDelegate>
Console.WriteLine("press 'a' key to increase total");
while (Console.ReadKey(true).KeyChar == 'a')
{
Console.WriteLine("adding one");
c.Add(1);
}
}
// <HandleEventDelegate>
static void c_ThresholdReached(object sender, ThresholdReachedEventArgs e)
{
Console.WriteLine($"The threshold of {e.Threshold} was reached at {e.TimeReached}.");
Environment.Exit(0);
}
// </HandleEventDelegate>
}
class CounterWithDelegate(int passedThreshold)
{
private readonly int _threshold = passedThreshold;
private int _total;
public void Add(int x)
{
_total += x;
// <RaiseEventDelegate>
if (_total >= _threshold)
{
ThresholdReachedEventArgs args = new();
args.Threshold = _threshold;
args.TimeReached = DateTime.Now;
OnThresholdReached(args);
}
// </RaiseEventDelegate>
}
// <RaiseEventMethodDelegate>
protected virtual void OnThresholdReached(ThresholdReachedEventArgs e)
{
ThresholdReached?.Invoke(this, e);
}
// </RaiseEventMethodDelegate>
// <DeclareEventWithDelegate>
public event ThresholdReachedEventHandler? ThresholdReached;
// </DeclareEventWithDelegate>
}
// <DeclareDelegateType>
public delegate void ThresholdReachedEventHandler(object sender, ThresholdReachedEventArgs e);
// </DeclareDelegateType>
// </ThresholdReachedWithDelegate>sample · vbdocs/standard/events/snippets/how-to-raise-and-consume-events/vb/EventWithDelegate.vbDeclareDelegateType
' <ThresholdReachedWithDelegate>
Module EventWithDelegate
Sub Main()
Dim c As New CounterWithDelegate(New Random().Next(10))
' <SubscribeEventDelegate>
AddHandler c.ThresholdReached, AddressOf c_ThresholdReached
' </SubscribeEventDelegate>
Console.WriteLine("press 'a' key to increase total")
While Console.ReadKey(True).KeyChar = "a"
Console.WriteLine("adding one")
c.Add(1)
End While
End Sub
' <HandleEventDelegate>
Sub c_ThresholdReached(sender As Object, e As ThresholdReachedEventArgs)
Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold, e.TimeReached)
Environment.Exit(0)
End Sub
' </HandleEventDelegate>
End Module
Class CounterWithDelegate
Private ReadOnly _threshold As Integer
Private _total As Integer
Public Sub New(passedThreshold As Integer)
_threshold = passedThreshold
End Sub
Public Sub Add(x As Integer)
_total += x
' <RaiseEventDelegate>
If (_total >= _threshold) Then
Dim args As New ThresholdReachedEventArgs With {
.Threshold = _threshold,
.TimeReached = Date.Now
}
OnThresholdReached(args)
End If
' </RaiseEventDelegate>
End Sub
' <RaiseEventMethodDelegate>
Protected Overridable Sub OnThresholdReached(e As ThresholdReachedEventArgs)
RaiseEvent ThresholdReached(Me, e)
End Sub
' </RaiseEventMethodDelegate>
' <DeclareEventWithDelegate>
Public Event ThresholdReached As ThresholdReachedEventHandler
' </DeclareEventWithDelegate>
End Class
' <DeclareDelegateType>
Delegate Sub ThresholdReachedEventHandler(sender As Object, e As ThresholdReachedEventArgs)
' </DeclareDelegateType>
' </ThresholdReachedWithDelegate>- Declare the event using your custom delegate type instead of System.EventHandler:
sample · csharpdocs/standard/events/snippets/how-to-raise-and-consume-events/csharp/EventWithDelegate.csDeclareEventWithDelegate
// <ThresholdReachedWithDelegate>
class EventWithDelegate
{
static void Main()
{
CounterWithDelegate c = new(new Random().Next(10));
// <SubscribeEventDelegate>
c.ThresholdReached += c_ThresholdReached;
// </SubscribeEventDelegate>
Console.WriteLine("press 'a' key to increase total");
while (Console.ReadKey(true).KeyChar == 'a')
{
Console.WriteLine("adding one");
c.Add(1);
}
}
// <HandleEventDelegate>
static void c_ThresholdReached(object sender, ThresholdReachedEventArgs e)
{
Console.WriteLine($"The threshold of {e.Threshold} was reached at {e.TimeReached}.");
Environment.Exit(0);
}
// </HandleEventDelegate>
}
class CounterWithDelegate(int passedThreshold)
{
private readonly int _threshold = passedThreshold;
private int _total;
public void Add(int x)
{
_total += x;
// <RaiseEventDelegate>
if (_total >= _threshold)
{
ThresholdReachedEventArgs args = new();
args.Threshold = _threshold;
args.TimeReached = DateTime.Now;
OnThresholdReached(args);
}
// </RaiseEventDelegate>
}
// <RaiseEventMethodDelegate>
protected virtual void OnThresholdReached(ThresholdReachedEventArgs e)
{
ThresholdReached?.Invoke(this, e);
}
// </RaiseEventMethodDelegate>
// <DeclareEventWithDelegate>
public event ThresholdReachedEventHandler? ThresholdReached;
// </DeclareEventWithDelegate>
}
// <DeclareDelegateType>
public delegate void ThresholdReachedEventHandler(object sender, ThresholdReachedEventArgs e);
// </DeclareDelegateType>
// </ThresholdReachedWithDelegate>sample · vbdocs/standard/events/snippets/how-to-raise-and-consume-events/vb/EventWithDelegate.vbDeclareEventWithDelegate
' <ThresholdReachedWithDelegate>
Module EventWithDelegate
Sub Main()
Dim c As New CounterWithDelegate(New Random().Next(10))
' <SubscribeEventDelegate>
AddHandler c.ThresholdReached, AddressOf c_ThresholdReached
' </SubscribeEventDelegate>
Console.WriteLine("press 'a' key to increase total")
While Console.ReadKey(True).KeyChar = "a"
Console.WriteLine("adding one")
c.Add(1)
End While
End Sub
' <HandleEventDelegate>
Sub c_ThresholdReached(sender As Object, e As ThresholdReachedEventArgs)
Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold, e.TimeReached)
Environment.Exit(0)
End Sub
' </HandleEventDelegate>
End Module
Class CounterWithDelegate
Private ReadOnly _threshold As Integer
Private _total As Integer
Public Sub New(passedThreshold As Integer)
_threshold = passedThreshold
End Sub
Public Sub Add(x As Integer)
_total += x
' <RaiseEventDelegate>
If (_total >= _threshold) Then
Dim args As New ThresholdReachedEventArgs With {
.Threshold = _threshold,
.TimeReached = Date.Now
}
OnThresholdReached(args)
End If
' </RaiseEventDelegate>
End Sub
' <RaiseEventMethodDelegate>
Protected Overridable Sub OnThresholdReached(e As ThresholdReachedEventArgs)
RaiseEvent ThresholdReached(Me, e)
End Sub
' </RaiseEventMethodDelegate>
' <DeclareEventWithDelegate>
Public Event ThresholdReached As ThresholdReachedEventHandler
' </DeclareEventWithDelegate>
End Class
' <DeclareDelegateType>
Delegate Sub ThresholdReachedEventHandler(sender As Object, e As ThresholdReachedEventArgs)
' </DeclareDelegateType>
' </ThresholdReachedWithDelegate>Add a
protected virtualmethod (Protected Overridablein Visual Basic) to raise the event.In C#, use the null-conditional operator (
?.) to guard against no subscribers (in Visual Basic,RaiseEventhandles this automatically):
sample · csharpdocs/standard/events/snippets/how-to-raise-and-consume-events/csharp/EventWithDelegate.csRaiseEventMethodDelegate
// <ThresholdReachedWithDelegate>
class EventWithDelegate
{
static void Main()
{
CounterWithDelegate c = new(new Random().Next(10));
// <SubscribeEventDelegate>
c.ThresholdReached += c_ThresholdReached;
// </SubscribeEventDelegate>
Console.WriteLine("press 'a' key to increase total");
while (Console.ReadKey(true).KeyChar == 'a')
{
Console.WriteLine("adding one");
c.Add(1);
}
}
// <HandleEventDelegate>
static void c_ThresholdReached(object sender, ThresholdReachedEventArgs e)
{
Console.WriteLine($"The threshold of {e.Threshold} was reached at {e.TimeReached}.");
Environment.Exit(0);
}
// </HandleEventDelegate>
}
class CounterWithDelegate(int passedThreshold)
{
private readonly int _threshold = passedThreshold;
private int _total;
public void Add(int x)
{
_total += x;
// <RaiseEventDelegate>
if (_total >= _threshold)
{
ThresholdReachedEventArgs args = new();
args.Threshold = _threshold;
args.TimeReached = DateTime.Now;
OnThresholdReached(args);
}
// </RaiseEventDelegate>
}
// <RaiseEventMethodDelegate>
protected virtual void OnThresholdReached(ThresholdReachedEventArgs e)
{
ThresholdReached?.Invoke(this, e);
}
// </RaiseEventMethodDelegate>
// <DeclareEventWithDelegate>
public event ThresholdReachedEventHandler? ThresholdReached;
// </DeclareEventWithDelegate>
}
// <DeclareDelegateType>
public delegate void ThresholdReachedEventHandler(object sender, ThresholdReachedEventArgs e);
// </DeclareDelegateType>
// </ThresholdReachedWithDelegate>sample · vbdocs/standard/events/snippets/how-to-raise-and-consume-events/vb/EventWithDelegate.vbRaiseEventMethodDelegate
' <ThresholdReachedWithDelegate>
Module EventWithDelegate
Sub Main()
Dim c As New CounterWithDelegate(New Random().Next(10))
' <SubscribeEventDelegate>
AddHandler c.ThresholdReached, AddressOf c_ThresholdReached
' </SubscribeEventDelegate>
Console.WriteLine("press 'a' key to increase total")
While Console.ReadKey(True).KeyChar = "a"
Console.WriteLine("adding one")
c.Add(1)
End While
End Sub
' <HandleEventDelegate>
Sub c_ThresholdReached(sender As Object, e As ThresholdReachedEventArgs)
Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold, e.TimeReached)
Environment.Exit(0)
End Sub
' </HandleEventDelegate>
End Module
Class CounterWithDelegate
Private ReadOnly _threshold As Integer
Private _total As Integer
Public Sub New(passedThreshold As Integer)
_threshold = passedThreshold
End Sub
Public Sub Add(x As Integer)
_total += x
' <RaiseEventDelegate>
If (_total >= _threshold) Then
Dim args As New ThresholdReachedEventArgs With {
.Threshold = _threshold,
.TimeReached = Date.Now
}
OnThresholdReached(args)
End If
' </RaiseEventDelegate>
End Sub
' <RaiseEventMethodDelegate>
Protected Overridable Sub OnThresholdReached(e As ThresholdReachedEventArgs)
RaiseEvent ThresholdReached(Me, e)
End Sub
' </RaiseEventMethodDelegate>
' <DeclareEventWithDelegate>
Public Event ThresholdReached As ThresholdReachedEventHandler
' </DeclareEventWithDelegate>
End Class
' <DeclareDelegateType>
Delegate Sub ThresholdReachedEventHandler(sender As Object, e As ThresholdReachedEventArgs)
' </DeclareDelegateType>
' </ThresholdReachedWithDelegate>- Populate the event data object and call the raise method when the condition is met:
sample · csharpdocs/standard/events/snippets/how-to-raise-and-consume-events/csharp/EventWithDelegate.csRaiseEventDelegate
// <ThresholdReachedWithDelegate>
class EventWithDelegate
{
static void Main()
{
CounterWithDelegate c = new(new Random().Next(10));
// <SubscribeEventDelegate>
c.ThresholdReached += c_ThresholdReached;
// </SubscribeEventDelegate>
Console.WriteLine("press 'a' key to increase total");
while (Console.ReadKey(true).KeyChar == 'a')
{
Console.WriteLine("adding one");
c.Add(1);
}
}
// <HandleEventDelegate>
static void c_ThresholdReached(object sender, ThresholdReachedEventArgs e)
{
Console.WriteLine($"The threshold of {e.Threshold} was reached at {e.TimeReached}.");
Environment.Exit(0);
}
// </HandleEventDelegate>
}
class CounterWithDelegate(int passedThreshold)
{
private readonly int _threshold = passedThreshold;
private int _total;
public void Add(int x)
{
_total += x;
// <RaiseEventDelegate>
if (_total >= _threshold)
{
ThresholdReachedEventArgs args = new();
args.Threshold = _threshold;
args.TimeReached = DateTime.Now;
OnThresholdReached(args);
}
// </RaiseEventDelegate>
}
// <RaiseEventMethodDelegate>
protected virtual void OnThresholdReached(ThresholdReachedEventArgs e)
{
ThresholdReached?.Invoke(this, e);
}
// </RaiseEventMethodDelegate>
// <DeclareEventWithDelegate>
public event ThresholdReachedEventHandler? ThresholdReached;
// </DeclareEventWithDelegate>
}
// <DeclareDelegateType>
public delegate void ThresholdReachedEventHandler(object sender, ThresholdReachedEventArgs e);
// </DeclareDelegateType>
// </ThresholdReachedWithDelegate>sample · vbdocs/standard/events/snippets/how-to-raise-and-consume-events/vb/EventWithDelegate.vbRaiseEventDelegate
' <ThresholdReachedWithDelegate>
Module EventWithDelegate
Sub Main()
Dim c As New CounterWithDelegate(New Random().Next(10))
' <SubscribeEventDelegate>
AddHandler c.ThresholdReached, AddressOf c_ThresholdReached
' </SubscribeEventDelegate>
Console.WriteLine("press 'a' key to increase total")
While Console.ReadKey(True).KeyChar = "a"
Console.WriteLine("adding one")
c.Add(1)
End While
End Sub
' <HandleEventDelegate>
Sub c_ThresholdReached(sender As Object, e As ThresholdReachedEventArgs)
Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold, e.TimeReached)
Environment.Exit(0)
End Sub
' </HandleEventDelegate>
End Module
Class CounterWithDelegate
Private ReadOnly _threshold As Integer
Private _total As Integer
Public Sub New(passedThreshold As Integer)
_threshold = passedThreshold
End Sub
Public Sub Add(x As Integer)
_total += x
' <RaiseEventDelegate>
If (_total >= _threshold) Then
Dim args As New ThresholdReachedEventArgs With {
.Threshold = _threshold,
.TimeReached = Date.Now
}
OnThresholdReached(args)
End If
' </RaiseEventDelegate>
End Sub
' <RaiseEventMethodDelegate>
Protected Overridable Sub OnThresholdReached(e As ThresholdReachedEventArgs)
RaiseEvent ThresholdReached(Me, e)
End Sub
' </RaiseEventMethodDelegate>
' <DeclareEventWithDelegate>
Public Event ThresholdReached As ThresholdReachedEventHandler
' </DeclareEventWithDelegate>
End Class
' <DeclareDelegateType>
Delegate Sub ThresholdReachedEventHandler(sender As Object, e As ThresholdReachedEventArgs)
' </DeclareDelegateType>
' </ThresholdReachedWithDelegate>- Subscribe to the event using the
+=operator (in Visual Basic,AddHandler):
sample · csharpdocs/standard/events/snippets/how-to-raise-and-consume-events/csharp/EventWithDelegate.csSubscribeEventDelegate
// <ThresholdReachedWithDelegate>
class EventWithDelegate
{
static void Main()
{
CounterWithDelegate c = new(new Random().Next(10));
// <SubscribeEventDelegate>
c.ThresholdReached += c_ThresholdReached;
// </SubscribeEventDelegate>
Console.WriteLine("press 'a' key to increase total");
while (Console.ReadKey(true).KeyChar == 'a')
{
Console.WriteLine("adding one");
c.Add(1);
}
}
// <HandleEventDelegate>
static void c_ThresholdReached(object sender, ThresholdReachedEventArgs e)
{
Console.WriteLine($"The threshold of {e.Threshold} was reached at {e.TimeReached}.");
Environment.Exit(0);
}
// </HandleEventDelegate>
}
class CounterWithDelegate(int passedThreshold)
{
private readonly int _threshold = passedThreshold;
private int _total;
public void Add(int x)
{
_total += x;
// <RaiseEventDelegate>
if (_total >= _threshold)
{
ThresholdReachedEventArgs args = new();
args.Threshold = _threshold;
args.TimeReached = DateTime.Now;
OnThresholdReached(args);
}
// </RaiseEventDelegate>
}
// <RaiseEventMethodDelegate>
protected virtual void OnThresholdReached(ThresholdReachedEventArgs e)
{
ThresholdReached?.Invoke(this, e);
}
// </RaiseEventMethodDelegate>
// <DeclareEventWithDelegate>
public event ThresholdReachedEventHandler? ThresholdReached;
// </DeclareEventWithDelegate>
}
// <DeclareDelegateType>
public delegate void ThresholdReachedEventHandler(object sender, ThresholdReachedEventArgs e);
// </DeclareDelegateType>
// </ThresholdReachedWithDelegate>sample · vbdocs/standard/events/snippets/how-to-raise-and-consume-events/vb/EventWithDelegate.vbSubscribeEventDelegate
' <ThresholdReachedWithDelegate>
Module EventWithDelegate
Sub Main()
Dim c As New CounterWithDelegate(New Random().Next(10))
' <SubscribeEventDelegate>
AddHandler c.ThresholdReached, AddressOf c_ThresholdReached
' </SubscribeEventDelegate>
Console.WriteLine("press 'a' key to increase total")
While Console.ReadKey(True).KeyChar = "a"
Console.WriteLine("adding one")
c.Add(1)
End While
End Sub
' <HandleEventDelegate>
Sub c_ThresholdReached(sender As Object, e As ThresholdReachedEventArgs)
Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold, e.TimeReached)
Environment.Exit(0)
End Sub
' </HandleEventDelegate>
End Module
Class CounterWithDelegate
Private ReadOnly _threshold As Integer
Private _total As Integer
Public Sub New(passedThreshold As Integer)
_threshold = passedThreshold
End Sub
Public Sub Add(x As Integer)
_total += x
' <RaiseEventDelegate>
If (_total >= _threshold) Then
Dim args As New ThresholdReachedEventArgs With {
.Threshold = _threshold,
.TimeReached = Date.Now
}
OnThresholdReached(args)
End If
' </RaiseEventDelegate>
End Sub
' <RaiseEventMethodDelegate>
Protected Overridable Sub OnThresholdReached(e As ThresholdReachedEventArgs)
RaiseEvent ThresholdReached(Me, e)
End Sub
' </RaiseEventMethodDelegate>
' <DeclareEventWithDelegate>
Public Event ThresholdReached As ThresholdReachedEventHandler
' </DeclareEventWithDelegate>
End Class
' <DeclareDelegateType>
Delegate Sub ThresholdReachedEventHandler(sender As Object, e As ThresholdReachedEventArgs)
' </DeclareDelegateType>
' </ThresholdReachedWithDelegate>Define the event handler.
The handler signature must match the custom delegate—
objectfor the sender and your event data class for the second parameter:
sample · csharpdocs/standard/events/snippets/how-to-raise-and-consume-events/csharp/EventWithDelegate.csHandleEventDelegate
// <ThresholdReachedWithDelegate>
class EventWithDelegate
{
static void Main()
{
CounterWithDelegate c = new(new Random().Next(10));
// <SubscribeEventDelegate>
c.ThresholdReached += c_ThresholdReached;
// </SubscribeEventDelegate>
Console.WriteLine("press 'a' key to increase total");
while (Console.ReadKey(true).KeyChar == 'a')
{
Console.WriteLine("adding one");
c.Add(1);
}
}
// <HandleEventDelegate>
static void c_ThresholdReached(object sender, ThresholdReachedEventArgs e)
{
Console.WriteLine($"The threshold of {e.Threshold} was reached at {e.TimeReached}.");
Environment.Exit(0);
}
// </HandleEventDelegate>
}
class CounterWithDelegate(int passedThreshold)
{
private readonly int _threshold = passedThreshold;
private int _total;
public void Add(int x)
{
_total += x;
// <RaiseEventDelegate>
if (_total >= _threshold)
{
ThresholdReachedEventArgs args = new();
args.Threshold = _threshold;
args.TimeReached = DateTime.Now;
OnThresholdReached(args);
}
// </RaiseEventDelegate>
}
// <RaiseEventMethodDelegate>
protected virtual void OnThresholdReached(ThresholdReachedEventArgs e)
{
ThresholdReached?.Invoke(this, e);
}
// </RaiseEventMethodDelegate>
// <DeclareEventWithDelegate>
public event ThresholdReachedEventHandler? ThresholdReached;
// </DeclareEventWithDelegate>
}
// <DeclareDelegateType>
public delegate void ThresholdReachedEventHandler(object sender, ThresholdReachedEventArgs e);
// </DeclareDelegateType>
// </ThresholdReachedWithDelegate>sample · vbdocs/standard/events/snippets/how-to-raise-and-consume-events/vb/EventWithDelegate.vbHandleEventDelegate
' <ThresholdReachedWithDelegate>
Module EventWithDelegate
Sub Main()
Dim c As New CounterWithDelegate(New Random().Next(10))
' <SubscribeEventDelegate>
AddHandler c.ThresholdReached, AddressOf c_ThresholdReached
' </SubscribeEventDelegate>
Console.WriteLine("press 'a' key to increase total")
While Console.ReadKey(True).KeyChar = "a"
Console.WriteLine("adding one")
c.Add(1)
End While
End Sub
' <HandleEventDelegate>
Sub c_ThresholdReached(sender As Object, e As ThresholdReachedEventArgs)
Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold, e.TimeReached)
Environment.Exit(0)
End Sub
' </HandleEventDelegate>
End Module
Class CounterWithDelegate
Private ReadOnly _threshold As Integer
Private _total As Integer
Public Sub New(passedThreshold As Integer)
_threshold = passedThreshold
End Sub
Public Sub Add(x As Integer)
_total += x
' <RaiseEventDelegate>
If (_total >= _threshold) Then
Dim args As New ThresholdReachedEventArgs With {
.Threshold = _threshold,
.TimeReached = Date.Now
}
OnThresholdReached(args)
End If
' </RaiseEventDelegate>
End Sub
' <RaiseEventMethodDelegate>
Protected Overridable Sub OnThresholdReached(e As ThresholdReachedEventArgs)
RaiseEvent ThresholdReached(Me, e)
End Sub
' </RaiseEventMethodDelegate>
' <DeclareEventWithDelegate>
Public Event ThresholdReached As ThresholdReachedEventHandler
' </DeclareEventWithDelegate>
End Class
' <DeclareDelegateType>
Delegate Sub ThresholdReachedEventHandler(sender As Object, e As ThresholdReachedEventArgs)
' </DeclareDelegateType>
' </ThresholdReachedWithDelegate>The following example shows the complete implementation:
sample · csharpdocs/standard/events/snippets/how-to-raise-and-consume-events/csharp/EventWithDelegate.csThresholdReachedWithDelegate
// <ThresholdReachedWithDelegate>
class EventWithDelegate
{
static void Main()
{
CounterWithDelegate c = new(new Random().Next(10));
// <SubscribeEventDelegate>
c.ThresholdReached += c_ThresholdReached;
// </SubscribeEventDelegate>
Console.WriteLine("press 'a' key to increase total");
while (Console.ReadKey(true).KeyChar == 'a')
{
Console.WriteLine("adding one");
c.Add(1);
}
}
// <HandleEventDelegate>
static void c_ThresholdReached(object sender, ThresholdReachedEventArgs e)
{
Console.WriteLine($"The threshold of {e.Threshold} was reached at {e.TimeReached}.");
Environment.Exit(0);
}
// </HandleEventDelegate>
}
class CounterWithDelegate(int passedThreshold)
{
private readonly int _threshold = passedThreshold;
private int _total;
public void Add(int x)
{
_total += x;
// <RaiseEventDelegate>
if (_total >= _threshold)
{
ThresholdReachedEventArgs args = new();
args.Threshold = _threshold;
args.TimeReached = DateTime.Now;
OnThresholdReached(args);
}
// </RaiseEventDelegate>
}
// <RaiseEventMethodDelegate>
protected virtual void OnThresholdReached(ThresholdReachedEventArgs e)
{
ThresholdReached?.Invoke(this, e);
}
// </RaiseEventMethodDelegate>
// <DeclareEventWithDelegate>
public event ThresholdReachedEventHandler? ThresholdReached;
// </DeclareEventWithDelegate>
}
// <DeclareDelegateType>
public delegate void ThresholdReachedEventHandler(object sender, ThresholdReachedEventArgs e);
// </DeclareDelegateType>
// </ThresholdReachedWithDelegate>sample · vbdocs/standard/events/snippets/how-to-raise-and-consume-events/vb/EventWithDelegate.vbThresholdReachedWithDelegate
' <ThresholdReachedWithDelegate>
Module EventWithDelegate
Sub Main()
Dim c As New CounterWithDelegate(New Random().Next(10))
' <SubscribeEventDelegate>
AddHandler c.ThresholdReached, AddressOf c_ThresholdReached
' </SubscribeEventDelegate>
Console.WriteLine("press 'a' key to increase total")
While Console.ReadKey(True).KeyChar = "a"
Console.WriteLine("adding one")
c.Add(1)
End While
End Sub
' <HandleEventDelegate>
Sub c_ThresholdReached(sender As Object, e As ThresholdReachedEventArgs)
Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold, e.TimeReached)
Environment.Exit(0)
End Sub
' </HandleEventDelegate>
End Module
Class CounterWithDelegate
Private ReadOnly _threshold As Integer
Private _total As Integer
Public Sub New(passedThreshold As Integer)
_threshold = passedThreshold
End Sub
Public Sub Add(x As Integer)
_total += x
' <RaiseEventDelegate>
If (_total >= _threshold) Then
Dim args As New ThresholdReachedEventArgs With {
.Threshold = _threshold,
.TimeReached = Date.Now
}
OnThresholdReached(args)
End If
' </RaiseEventDelegate>
End Sub
' <RaiseEventMethodDelegate>
Protected Overridable Sub OnThresholdReached(e As ThresholdReachedEventArgs)
RaiseEvent ThresholdReached(Me, e)
End Sub
' </RaiseEventMethodDelegate>
' <DeclareEventWithDelegate>
Public Event ThresholdReached As ThresholdReachedEventHandler
' </DeclareEventWithDelegate>
End Class
' <DeclareDelegateType>
Delegate Sub ThresholdReachedEventHandler(sender As Object, e As ThresholdReachedEventArgs)
' </DeclareDelegateType>
' </ThresholdReachedWithDelegate>