Home >Backend Development >C++ >How to Make C# Events Asynchronous?
Elegant handling of asynchronous events in C#
In a C# application, if a class contains an event (such as the 'GameShuttingDown' event) and the event handler is asynchronous, there may be a problem that the game closes before the waiting event handler completes. This is because the event itself is synchronous, but the handler is asynchronous.
Although it is possible to use asynchronous mechanisms to replace events, this will lose the simplicity of events. A better approach is to maintain the expressiveness of events while enabling asynchronous processing. We can do this by customizing the delegate type instead of using the standard EventHandler
.
The following example shows how:
<code class="language-csharp">public class A { public event Func<object, EventArgs, Task> Shutdown; public async Task OnShutdown() { var handler = Shutdown; if (handler == null) { return; } var invocationList = handler.GetInvocationList(); var handlerTasks = invocationList.Select(h => ((Func<object, EventArgs, Task>)h)(this, EventArgs.Empty)).ToArray(); await Task.WhenAll(handlerTasks); } }</code>
In the OnShutdown()
method, we first get a local copy of the event delegate. We then call all handlers and store the returned tasks in an array. Finally, we use Task.WhenAll()
to wait for all tasks to complete. This is more concise than loop iteration.
The following is a simple console program that demonstrates usage:
<code class="language-csharp">public class Program { public static void Main(string[] args) { var a = new A(); a.Shutdown += Handler1; a.Shutdown += Handler2; a.Shutdown += Handler3; a.OnShutdown().Wait(); } public static async Task Handler1(object sender, EventArgs e) { Console.WriteLine("启动关闭处理程序 #1"); await Task.Delay(1000); Console.WriteLine("关闭处理程序 #1 完成"); } public static async Task Handler2(object sender, EventArgs e) { Console.WriteLine("启动关闭处理程序 #2"); await Task.Delay(5000); Console.WriteLine("关闭处理程序 #2 完成"); } public static async Task Handler3(object sender, EventArgs e) { Console.WriteLine("启动关闭处理程序 #3"); await Task.Delay(2000); Console.WriteLine("关闭处理程序 #3 完成"); } }</code>
This approach retains the simplicity of events while ensuring that handlers execute asynchronously, avoiding synchronous blocking issues. Using LINQ's Select
method simplifies the code, making it easier to read and maintain.
The above is the detailed content of How to Make C# Events Asynchronous?. For more information, please follow other related articles on the PHP Chinese website!