問題: 待機可能なイベントの処理
C# アプリケーションでは、アプリケーションを閉じる前に非同期データ保存タスクを確実に完了させるために待機可能なイベント ハンドラーが必要という課題に直面することがあります。現在、イベントの同期的な性質により、非同期保存が完了する前にゲームが終了します。
解決策: カスタム イベント委任
推奨されるアプローチは、void の代わりに Task を返すカスタム イベント デリゲートを作成することです。こうすることで、ハンドラーを待機し、続行する前にハンドラーが完了したことを確認できます。
実績
<code class="language-csharp">class Game { public event Func<object, EventArgs, Task> GameShuttingDown; public async Task Shutdown() { Func<object, EventArgs, Task> handler = GameShuttingDown; if (handler == null) return; Delegate[] invocationList = handler.GetInvocationList(); Task[] handlerTasks = new Task[invocationList.Length]; for (int i = 0; i < invocationList.Length; i++) { handlerTasks[i] = ((Func<object, EventArgs, Task>)invocationList[i])(this, EventArgs.Empty); } await Task.WhenAll(handlerTasks); } }</code>
使用例
<code class="language-csharp">Game game = new Game(); game.GameShuttingDown += async (sender, args) => await SaveUserData(); await game.Shutdown();</code>
代替: 明示的に登録して呼び出します
もう 1 つのオプションは、コールバックを登録し、必要に応じて明示的に呼び出すことです。
<code class="language-csharp">class Game { private List<Func<Task>> _shutdownCallbacks = new List<Func<Task>>(); public void RegisterShutdownCallback(Func<Task> callback) { _shutdownCallbacks.Add(callback); } public async Task Shutdown() { var callbackTasks = new List<Task>(); foreach (var callback in _shutdownCallbacks) { callbackTasks.Add(callback()); } await Task.WhenAll(callbackTasks); } }</code>
結論
非同期イベント ハンドラーは設計上の最良の選択ではないかもしれませんが、カスタム イベント デリゲートを使用するか、コールバックを登録して明示的に呼び出すことにより、待機可能な方法で実装できます。
以上がアプリケーションのシャットダウン前に非同期データを保存するために C# で待機可能なイベント ハンドラーを作成するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。