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で完了通知も受け取れます