LoginSignup
5
3

More than 5 years have passed since last update.

async void 回避策?

Posted at

neue cc さんの記事を拝見して思いついたことのメモ。
asyncの落とし穴Part3, async voidを避けるべき100億の理由

(※思い付きですので、見当違いだったりするかもしれません。ご意見を頂けると助かりす。)

イベントハンドラ内では Observable.Create(With async) を使う

引数に、戻り値がTaskのデリゲートを渡すObservable.Createのオーバーロードを使用します。

public static IObservable<T> Create<T>(Func<IObserver<T>, CancellationToken, Task> subscribeAsync)

中身はこんな感じ
※参考: http://go4answers.webhost4life.com/Example/observablecreate-async-166592.aspx

public static IObservable<T> Create<T>(Func<IObserver<T>, CancellationToken, Task> subscribeAsync)
{
    return Observable.Create<T>(observer =>
        {
            var cts = new CancellationTokenSource();
            var task = subscribeAsync(observer, cts.Token);
            var subscription = task.ToObservable().Subscribe(_ => { }, observer.OnError, observer.OnCompleted);
            return new CompositeDisposable(subscription, new CancellationDisposable(cts));
        });
}

引数のデリケート内で、とある非同期のメソッドを記述します。

public static async Task ToaruAsyncMethod()
{
    await Task.Delay(2000);
}

private void NanikanoEventHandler(Object sender, EventArgs e)
{
     var io = ObservableExt.Create<Unit>(async (observer, ct) =>
            {
                await ToaruMethod();
            });
    disposable = io.Subscribe(
            _ => { }, 
            error => logger.WriteLine("error! " + error.Message), 
            () => logger.WriteLine("completed!"));
}
  • イベントハンドラにasync を書かなくて済みます
  • OnErrorでエラーのハンドリングができます
  • OnCompletedで完了通知も受け取れます
5
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3