C#:非同期なイベント?
執筆日時:
たとえばこんなコードがあるとする。ラムダ式でイベントハンドラを実装する、よくあるヤツ。
public void Run(IBackgroundTaskInstance taskInstance) { taskInstance.Canceled += (sender, reason) => { Hoge(); }; }
イベントハンドラ内で非同期コードがある場合は、こんな感じになる。
public void Run(IBackgroundTaskInstance taskInstance) { taskInstance.Canceled += async (sender, reason) => { await Hoge(); }; }
async/await を付け足すだけなので、そんなに難しくはない。
次に、イベントハンドラのコードが肥大化してきたので、これを外に出すことにする。
非同期じゃない場合はこんな感じ。
public void Run(IBackgroundTaskInstance taskInstance) { taskInstance.Canceled += taskInstanceCanceled; }private void taskInstanceCanceled( IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason) { Hoge(); : : }
これをさっきみたいに非同期にすると、
public void Run(IBackgroundTaskInstance taskInstance) { taskInstance.Canceled += taskInstanceCanceled; // taskInstance.Canceled += async taskInstanceCanceled; } private async Task taskInstanceCanceled( IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason) { await Hoge(); : : }
になると思うんだけど、
taskInstance.Canceled += taskInstanceCanceled;
ここでエラーになる(taskInstanceCanceled の返り値が void ではなく Task なので)。
しょうがないので、ちょっと考えてこうした。
public void Run(IBackgroundTaskInstance taskInstance) { taskInstance.Canceled += async (sender, reason) => { await taskInstanceCanceled(sender, reason); }; } private async Task taskInstanceCanceled( IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason) { await Hoge(); : : }
動いたっぽいんだけどなんかしっくりこないので、今度詳しい人に聞いてみたい。