Rumah >pembangunan bahagian belakang >C++ >Bagaimana untuk Mengendalikan Acara Asynchronous dalam C# Menggunakan Async Delegates?
Perwakilan tak segerak C#: tunggu acara tak segerak dengan anggun
Dalam C#, acara secara tradisinya mengembalikan kekosongan, yang menjadikannya tidak serasi dengan operasi tak segerak. Masalah ini timbul apabila pengendali acara perlu melakukan tugas tak segerak sebelum memberitahu komponen lain. Senario berikut meneroka masalah ini dan menyediakan penyelesaian menggunakan perwakilan tak segerak.
Soalan:
Kod di bawah menunjukkan acara bernama GameShuttingDown
yang menyala apabila permainan ditutup. Setiap pengendali acara harus menyimpan data secara tidak segerak sebelum permainan ditutup. Walau bagaimanapun, pengendali dipanggil dengan kaedah tidak sah, menyebabkan permainan ditutup sebelum simpanan selesai.
<code class="language-csharp">public event EventHandler<EventArgs> GameShuttingDown; public async Task ShutdownGame() { await this.NotifyGameShuttingDown(); await this.SaveWorlds(); this.NotifyGameShutDown(); } private async Task SaveWorlds() { foreach (DefaultWorld world in this.Worlds) { await this.worldService.SaveWorld(world); } } protected virtual void NotifyGameShuttingDown() { var handler = this.GameShuttingDown; if (handler == null) { return; } handler(this, new EventArgs()); }</code>
Penyelesaian:
Untuk menyelesaikan masalah ini, kita boleh menggunakan perwakilan tak segerak yang mengembalikan tugas. Dengan cara ini kita boleh memanggil pengendali secara tidak segerak dan menunggu hasilnya.
Gantikan acara GameShuttingDown
sedia ada dengan jenis perwakilan tak segerak:
<code class="language-csharp">public event Func<object, EventArgs, Task> GameShuttingDown;</code>
Ubah suai kaedah NotifyGameShuttingDown
untuk memanggil pengendali dan tunggu sehingga selesai:
<code class="language-csharp">protected virtual async Task NotifyGameShuttingDown() { 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>
Penggunaan:
Langgan acara GameShuttingDown
menggunakan jenis perwakilan tak segerak baharu:
<code class="language-csharp">DefaultGame.GameShuttingDown += async (sender, args) => await this.repo.Save(blah);</code>
Pendekatan ini memastikan bahawa permainan hanya akan ditutup selepas semua operasi simpan tak segerak dalam pengendali acara selesai.
Atas ialah kandungan terperinci Bagaimana untuk Mengendalikan Acara Asynchronous dalam C# Menggunakan Async Delegates?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!