Heim >Backend-Entwicklung >C++ >Wie mache ich C#-Ereignisse asynchron?
Eleganter Umgang mit asynchronen Ereignissen in C#
Wenn in einer C#-Anwendung eine Klasse ein Ereignis enthält (z. B. das Ereignis „GameShuttingDown“) und der Ereignishandler asynchron ist, kann es zu einem Problem kommen, dass das Spiel geschlossen wird, bevor der wartende Ereignishandler abgeschlossen ist. Dies liegt daran, dass das Ereignis selbst synchron ist, der Handler jedoch asynchron.
Obwohl es möglich ist, asynchrone Mechanismen zum Ersetzen von Ereignissen zu verwenden, geht dadurch die Einfachheit von Ereignissen verloren. Ein besserer Ansatz besteht darin, die Ausdruckskraft von Ereignissen beizubehalten und gleichzeitig eine asynchrone Verarbeitung zu ermöglichen. Wir können dies erreichen, indem wir den Delegatentyp anpassen, anstatt den Standard EventHandler
zu verwenden.
Das folgende Beispiel zeigt, wie:
<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>
Bei der OnShutdown()
-Methode erhalten wir zunächst eine lokale Kopie des Ereignisdelegierten. Anschließend rufen wir alle Handler auf und speichern die zurückgegebenen Aufgaben in einem Array. Schließlich verwenden wir Task.WhenAll()
, um zu warten, bis alle Aufgaben abgeschlossen sind. Dies ist prägnanter als die Schleifeniteration.
Das Folgende ist ein einfaches Konsolenprogramm, das die Verwendung demonstriert:
<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>
Dieser Ansatz behält die Einfachheit von Ereignissen bei und stellt gleichzeitig sicher, dass Handler asynchron ausgeführt werden, wodurch synchrone Blockierungsprobleme vermieden werden. Die Verwendung der Select
-Methode von LINQ vereinfacht den Code und erleichtert so das Lesen und Warten.
Das obige ist der detaillierte Inhalt vonWie mache ich C#-Ereignisse asynchron?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!