web-dev-qa-db-ja.com

Observable.FromAsyncとTask.ToObservable

これらの方法のいずれかを他の方法よりもいつ使用するかについて、誰かが舵取りをしていますか? TPL TaskからObservableに変換するという点で同じことをしているようです。

Observable.FromAsyncはキャンセルトークンをサポートしているようです。これは、オブザーバブルが破棄された場合にタスクを生成するメソッドが協調キャンセルに参加できるようにする微妙な違いである可能性があります。

なぜあなたが一方を他方の上に使用するのかについて明白な何かが欠けているのではないかと思っています。

ありがとう

13
user630190

コードを見ると、(少なくとも一部のフローでは)_Observable.FromAsync_が.ToObservable() *を呼び出しているように見えます。それらは意味的に同等でなければならないという意図があると確信しています(同じパラメーター(スケジューラー、キャンセルトークンなど)を渡すと仮定します)。

1つは連鎖/流暢な構文に適していますが、単独で読む方がよい場合があります。どちらのコーディングスタイルを好むか。

* https://github.com/Reactive-Extensions/Rx.NET/blob/859e6159cb07be67fd36b18c2ae2b9a62979cb6d/Rx.NET/Source/System.Reactive.Linq/Reactive/Linq/QueryLanguage.Async.cs#L727 ==

5
Lee Campbell

_Observable.FromAsync_は、_Func<Task>_または_Func<Task<TResult>>_の形式でTaskFactoryを受け入れます。この場合、タスクは、オブザーバブルがサブスクライブされている場合にのみ作成および実行されます。

一方、.ToObservable()には、すでに作成された(したがって開始された)タスクが必要です。

13
Sickboy

@Sickboyの答えは正しいです。

  • Observable.FromAsync()は、サブスクリプションの瞬間にタスクを開始します。
  • Task.ToObservable()はすでに実行中のタスクが必要です。

_Observable.FromAsync_の用途の1つは、非同期メソッドへの複数の呼び出しの再入可能性を制御することです。

これは、これら2つの方法が同等ではない例です。

_//ob is some IObservable<T>

//ExecuteQueryAsync is some async method
//Here, ExecuteQueryAsync will run **serially**, the second call will start
//only when the first one is already finished. This is an important property
//if ExecuteQueryAsync doesn't support reentrancy
ob
.Select(x => Observable.FromAsync(() => ExecuteQueryAsync(x))
.Concat()
.ObserveOnDispatcher()
.Subscribe(action)
_

vs

_//ob is some IObservable<T>

//ExecuteQueryAsync is some async method
//Even when the `Subscribe` action order will be the same as the first 
//example because of the `Concat`, ExecuteQueryAsync calls could be     
//parallel, the second call to the method could start before the end of the 
//first call. 
.Select(x => ExecuteQueryAsync(x).ToObservable())
.Concat()
.Subscribe(action)
_

最初の例では、_Observable.FromAsync_であるため、元のディスパッチャでactionが確実に実行されるように、ObserveOn()またはObserveOnDispatcher()メソッドが必要になる場合があることに注意してください。タスクを待機しないため、利用可能なディスパッチャで継続が実行されます

10
Rafael

CancellationTokenを使用できることに加えて、FromAsyncは遅延でラップするため、サブスクリプション時の条件に基づいてタスクロジックを変更できます。タスクは開始されず、内部的にtask.ToObservableが呼び出されることに注意してください。 Funcを使用すると、タスクを作成するときにタスクを開始できます。

0
user487779