Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions docs/standard/events/how-to-raise-and-consume-events.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
title: "How to: Raise and Consume Events"
description: Raise & consume events in .NET. See examples that use the EventHandler delegate, the EventHandler<TEventArgs> delegate, & a custom delegate.
ms.date: 10/20/2025
ms.custom: devdivchpfy22
dev_langs:
- "csharp"
- "vb"
Expand All @@ -11,31 +10,32 @@ helpviewer_keywords:
- "raising events"
- "events [.NET], samples"
---
# How to: Raise and Consume Events
# How to: Raise and consume events

The examples in this article show how to work with events. They include examples of the <xref:System.EventHandler> delegate, the <xref:System.EventHandler%601> delegate, and a custom delegate to illustrate events with and without data.
The examples in this article show how to work with events. They include examples of the <xref:System.EventHandler> delegate, the <xref:System.EventHandler`1> delegate, and a custom delegate to illustrate events with and without data.

The examples use concepts described in the [Events](index.md) article.

## Example 1

The first example shows how to raise and consume an event that doesn't have data. It contains a class named `Counter` that has an event called `ThresholdReached`. This event is raised when a counter value equals or exceeds a threshold value. The <xref:System.EventHandler> delegate is associated with the event because no event data is provided.
This first example shows how to raise and consume an event that doesn't have data. It contains a class named `Counter` that has an event called `ThresholdReached`. This event is raised when a counter value equals or exceeds a threshold value. The <xref:System.EventHandler> delegate is associated with the event because no event data is provided.

[!code-csharp[EventsOverview#5](../../../samples/snippets/csharp/VS_Snippets_CLR/eventsoverview/cs/programnodata.cs#5)]
[!code-vb[EventsOverview#5](../../../samples/snippets/visualbasic/VS_Snippets_CLR/eventsoverview/vb/module1nodata.vb#5)]
[!code-csharp[EventsOverview#5](./snippets/raise-consume/csharp/programnodata.cs#5)]
[!code-vb[EventsOverview#5](./snippets/raise-consume/vb/module1nodata.vb#5)]

## Example 2

The second example shows how to raise and consume an event that provides data. The <xref:System.EventHandler%601> delegate is associated with the event, and an instance of a custom event data object is provided.
[!code-csharp[EventsOverview#6](../../../samples/snippets/csharp/VS_Snippets_CLR/eventsoverview/cs/programwithdata.cs#6)]
[!code-vb[EventsOverview#6](../../../samples/snippets/visualbasic/VS_Snippets_CLR/eventsoverview/vb/module1withdata.vb#6)]
This second example shows how to raise and consume an event that provides data. The <xref:System.EventHandler`1> delegate is associated with the event, and an instance of a custom event data object is provided.

[!code-csharp[EventsOverview#6](./snippets/raise-consume/csharp/programwithdata.cs#6)]
[!code-vb[EventsOverview#6](./snippets/raise-consume/vb/module1withdata.vb#6)]

## Example 3

The third example shows how to declare a delegate for an event. The delegate is named `ThresholdReachedEventHandler`. This example is just an illustration. Typically, you don't have to declare a delegate for an event because you can use either the <xref:System.EventHandler> or the <xref:System.EventHandler%601> delegate. You should declare a delegate only in rare scenarios, such as making your class available to legacy code that can't use generics.
This third example shows how to declare a delegate for an event. The delegate is named `ThresholdReachedEventHandler`. This example is just an illustration. Typically, you don't have to declare a delegate for an event because you can use either the <xref:System.EventHandler> or the <xref:System.EventHandler`1> delegate. You should declare a delegate only in rare scenarios, such as making your class available to legacy code that can't use generics.

[!code-csharp[EventsOverview#7](../../../samples/snippets/csharp/VS_Snippets_CLR/eventsoverview/cs/programwithdelegate.cs#7)]
[!code-vb[EventsOverview#7](../../../samples/snippets/visualbasic/VS_Snippets_CLR/eventsoverview/vb/module1withdelegate.vb#7)]
[!code-csharp[EventsOverview#7](./snippets/raise-consume/csharp/programwithdelegate.cs#7)]
[!code-vb[EventsOverview#7](./snippets/raise-consume/vb/module1withdelegate.vb#7)]

## See also

Expand Down
18 changes: 8 additions & 10 deletions docs/standard/events/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ helpviewer_keywords:
- "events [.NET]"
- "events [.NET Core]"
- "events [.NET]"
ms.assetid: b6f65241-e0ad-4590-a99f-200ce741bb1f
#customer intent: As a .NET developer, I want to raise and handle .NET events based on the delegate model, so I can enable subscribers to register with or receive notifications from providers.

---
# Handle and raise events
Expand All @@ -33,8 +31,8 @@ Typically, to raise an event, you add a method that is marked as `protected` and

The following example shows how to declare an event named `ThresholdReached`. The event is associated with the <xref:System.EventHandler> delegate and raised in a method named `OnThresholdReached`:

[!code-csharp[EventsOverview#1](~/samples/snippets/csharp/VS_Snippets_CLR/eventsoverview/cs/programtruncated.cs#1)]
[!code-vb[EventsOverview#1](~/samples/snippets/visualbasic/VS_Snippets_CLR/eventsoverview/vb/module1truncated.vb#1)]
[!code-csharp[EventsOverview#1](./snippets/raise-consume/csharp/programtruncated.cs#1)]
[!code-vb[EventsOverview#1](./snippets/raise-consume/vb/module1truncated.vb#1)]

## Declare delegate signatures for event handlers

Expand All @@ -48,8 +46,8 @@ Delegates are [multicast](xref:System.MulticastDelegate) class objects, which me

Use the <xref:System.EventHandler> and <xref:System.EventHandler%601> delegate types to define the needed delegate. You mark a delegate with the `delegate` type in [C#](../../csharp/language-reference/builtin-types/reference-types.md#the-delegate-type) or the `Delegate` type in [Visual Basic](../../visual-basic/language-reference/statements/delegate-statement.md) in the declaration. The following example shows how to declare a delegate named `ThresholdReachedEventHandler`:

[!code-csharp[EventsOverview#4](~/samples/snippets/csharp/VS_Snippets_CLR/eventsoverview/cs/programtruncated.cs#4)]
[!code-vb[EventsOverview#4](~/samples/snippets/visualbasic/VS_Snippets_CLR/eventsoverview/vb/module1truncated.vb#4)]
[!code-csharp[EventsOverview#4](./snippets/raise-consume/csharp/programtruncated.cs#4)]
[!code-vb[EventsOverview#4](./snippets/raise-consume/vb/module1truncated.vb#4)]

## Work with event data classes

Expand All @@ -61,17 +59,17 @@ You can create a class that derives from the <xref:System.EventArgs> class to pr

The following example shows an event data class named `ThresholdReachedEventArgs` that contains properties that are specific to the event being raised:

[!code-csharp[EventsOverview#3](~/samples/snippets/csharp/VS_Snippets_CLR/eventsoverview/cs/programtruncated.cs#3)]
[!code-vb[EventsOverview#3](~/samples/snippets/visualbasic/VS_Snippets_CLR/eventsoverview/vb/module1truncated.vb#3)]
[!code-csharp[EventsOverview#3](./snippets/raise-consume/csharp/programtruncated.cs#3)]
[!code-vb[EventsOverview#3](./snippets/raise-consume/vb/module1truncated.vb#3)]

## Respond to events with handlers

To respond to an event, you define an event handler method in the event receiver. This method must match the signature of the delegate for the event you're handling. In the event handler, you perform the actions that are required when the event is raised, such as collecting user input after the user presses a button. To receive notifications when the event occurs, your event handler method must subscribe to the event.

The following example shows an event handler method named `c_ThresholdReached` that matches the signature for the <xref:System.EventHandler> delegate. The method subscribes to the `ThresholdReached` event:

[!code-csharp[EventsOverview#2](~/samples/snippets/csharp/VS_Snippets_CLR/eventsoverview/cs/programtruncated.cs#2)]
[!code-vb[EventsOverview#2](~/samples/snippets/visualbasic/VS_Snippets_CLR/eventsoverview/vb/module1truncated.vb#2)]
[!code-csharp[EventsOverview#2](./snippets/raise-consume/csharp/programtruncated.cs#2)]
[!code-vb[EventsOverview#2](./snippets/raise-consume/vb/module1truncated.vb#2)]

## Use static and dynamic event handlers

Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
// <snippet5>
using System;

namespace ConsoleApplication1
namespace ConsoleApplication1
{
// <snippet5>
class ProgramOne
{
static void Main(string[] args)
static void Main()
{
Counter c = new Counter(new Random().Next(10));
Counter c = new(new Random().Next(10));
c.ThresholdReached += c_ThresholdReached;

Console.WriteLine("press 'a' key to increase total");
Expand All @@ -18,33 +16,28 @@ static void Main(string[] args)
}
}

static void c_ThresholdReached(object sender, EventArgs e)
static void c_ThresholdReached(object? sender, EventArgs e)
{
Console.WriteLine("The threshold was reached.");
Environment.Exit(0);
}
}

class Counter
class Counter(int passedThreshold)
{
private int threshold;
private int total;

public Counter(int passedThreshold)
{
threshold = passedThreshold;
}
private readonly int _threshold = passedThreshold;
private int _total;

public void Add(int x)
{
total += x;
if (total >= threshold)
_total += x;
if (_total >= _threshold)
{
ThresholdReached?.Invoke(this, EventArgs.Empty);
}
}

public event EventHandler ThresholdReached;
public event EventHandler? ThresholdReached;
}
// </snippet5>
}
// </snippet5>
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System;

namespace ConsoleApplication2
namespace ConsoleApplication2
{
// <snippet2>
class ProgramTwo
Expand All @@ -10,10 +8,10 @@ static void Main()
var c = new Counter();
c.ThresholdReached += c_ThresholdReached;

// provide remaining implementation for the class
// Provide remaining implementation for the class...
}

static void c_ThresholdReached(object sender, EventArgs e)
static void c_ThresholdReached(object? sender, EventArgs e)
{
Console.WriteLine("The threshold was reached.");
}
Expand All @@ -23,14 +21,14 @@ static void c_ThresholdReached(object sender, EventArgs e)
// <snippet1>
class Counter
{
public event EventHandler ThresholdReached;
public event EventHandler? ThresholdReached;

protected virtual void OnThresholdReached(EventArgs e)
{
ThresholdReached?.Invoke(this, e);
}

// provide remaining implementation for the class
// Provide remaining implementation for the class...
}
// </snippet1>

Expand All @@ -43,6 +41,8 @@ public class ThresholdReachedEventArgs : EventArgs
// </snippet3>

//<snippet4>
public delegate void ThresholdReachedEventHandler(object sender, ThresholdReachedEventArgs e);
public delegate void ThresholdReachedEventHandler(
object sender,
ThresholdReachedEventArgs e);
//</snippet4>
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
// <snippet6>
using System;

namespace ConsoleApplication3
namespace ConsoleApplication3
{
// <snippet6>
class ProgramThree
{
static void Main(string[] args)
static void Main()
{
Counter c = new Counter(new Random().Next(10));
Counter c = new(new Random().Next(10));
c.ThresholdReached += c_ThresholdReached;

Console.WriteLine("press 'a' key to increase total");
Expand All @@ -18,51 +16,42 @@ static void Main(string[] args)
}
}

static void c_ThresholdReached(object sender, ThresholdReachedEventArgs e)
static void c_ThresholdReached(object? sender, ThresholdReachedEventArgs e)
{
Console.WriteLine($"The threshold of {e.Threshold} was reached at {e.TimeReached}.");
Environment.Exit(0);
}
}

class Counter
class Counter(int passedThreshold)
{
private int threshold;
private int total;

public Counter(int passedThreshold)
{
threshold = passedThreshold;
}
private readonly int _threshold = passedThreshold;
private int _total;

public void Add(int x)
{
total += x;
if (total >= threshold)
_total += x;
if (_total >= _threshold)
{
ThresholdReachedEventArgs args = new ThresholdReachedEventArgs();
args.Threshold = threshold;
args.Threshold = _threshold;
args.TimeReached = DateTime.Now;
OnThresholdReached(args);
}
}

protected virtual void OnThresholdReached(ThresholdReachedEventArgs e)
{
EventHandler<ThresholdReachedEventArgs> handler = ThresholdReached;
if (handler != null)
{
handler(this, e);
}
ThresholdReached?.Invoke(this, e);
}

public event EventHandler<ThresholdReachedEventArgs> ThresholdReached;
public event EventHandler<ThresholdReachedEventArgs>? ThresholdReached;
}

public class ThresholdReachedEventArgs : EventArgs
{
public int Threshold { get; set; }
public DateTime TimeReached { get; set; }
}
// </snippet6>
}
// </snippet6>
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
// <snippet7>
using System;

namespace ConsoleApplication4
namespace ConsoleApplication4
{
// <snippet7>
class ProgramFour
{
static void Main(string[] args)
static void Main()
{
Counter c = new Counter(new Random().Next(10));
Counter c = new(new Random().Next(10));
c.ThresholdReached += c_ThresholdReached;

Console.WriteLine("press 'a' key to increase total");
Expand All @@ -27,33 +25,29 @@ static void c_ThresholdReached(Object sender, ThresholdReachedEventArgs e)

class Counter
{
private int threshold;
private int total;
private readonly int _threshold;
private int _total;

public Counter(int passedThreshold)
{
threshold = passedThreshold;
_threshold = passedThreshold;
}

public void Add(int x)
{
total += x;
if (total >= threshold)
_total += x;
if (_total >= _threshold)
{
ThresholdReachedEventArgs args = new ThresholdReachedEventArgs();
args.Threshold = threshold;
ThresholdReachedEventArgs args = new();
args.Threshold = _threshold;
args.TimeReached = DateTime.Now;
OnThresholdReached(args);
}
}

protected virtual void OnThresholdReached(ThresholdReachedEventArgs e)
{
ThresholdReachedEventHandler handler = ThresholdReached;
if (handler != null)
{
handler(this, e);
}
ThresholdReached?.Invoke(this, e);
}

public event ThresholdReachedEventHandler ThresholdReached;
Expand All @@ -65,6 +59,8 @@ public class ThresholdReachedEventArgs : EventArgs
public DateTime TimeReached { get; set; }
}

public delegate void ThresholdReachedEventHandler(Object sender, ThresholdReachedEventArgs e);
public delegate void ThresholdReachedEventHandler(
object sender,
ThresholdReachedEventArgs e);
// </snippet7>
}
// </snippet7>
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>true</ImplicitUsings>
<OutputType>Exe</OutputType>
Expand Down
Loading