C#의 우아한 비동기 이벤트 처리
C# 애플리케이션에서 클래스에 이벤트(예: 'GameShuttingDown' 이벤트)가 포함되어 있고 이벤트 핸들러가 비동기식인 경우 대기 이벤트 핸들러가 완료되기 전에 게임이 종료되는 문제가 있을 수 있습니다. 이는 이벤트 자체는 동기적이지만 핸들러는 비동기적이기 때문입니다.
비동기식 메커니즘을 사용하여 이벤트를 대체할 수 있지만 이렇게 하면 이벤트의 단순성이 손실됩니다. 더 나은 접근 방식은 비동기 처리를 활성화하면서 이벤트의 표현력을 유지하는 것입니다. 표준 EventHandler
을 사용하는 대신 대리자 유형을 사용자 정의하여 이를 수행할 수 있습니다.
다음 예에서는 방법을 보여줍니다.
<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>
OnShutdown()
메서드에서는 먼저 이벤트 대리자의 로컬 복사본을 얻습니다. 그런 다음 모든 핸들러를 호출하고 반환된 작업을 배열에 저장합니다. 마지막으로 Task.WhenAll()
을 사용하여 모든 작업이 완료될 때까지 기다립니다. 이는 루프 반복보다 더 간결합니다.
다음은 사용법을 보여주는 간단한 콘솔 프로그램입니다.
<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>
이 접근 방식은 이벤트의 단순성을 유지하는 동시에 핸들러가 비동기적으로 실행되도록 보장하여 동기 차단 문제를 방지합니다. LINQ의 Select
메서드를 사용하면 코드가 단순화되어 읽기 및 유지 관리가 더 쉬워집니다.
위 내용은 C# 이벤트를 비동기식으로 만드는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!