Observable.FromAsync vs Task.ToObservable

时间:2016-01-21 18:03:24

标签: c# .net system.reactive

有没有人知道何时使用其中一种方法而不是另一种方法。他们似乎做了同样的事情,因为他们从TPL Task转换为Observable

Observable.FromAsync似乎支持取消令牌,这可能是微妙的差异,如果处置了可观察量,则允许生成任务的方法参与合作取消。

只是想知道我是否遗漏了一些明显的问题,为什么你要使用另一个而不是另一个。

由于

4 个答案:

答案 0 :(得分:9)

Observable.FromAsync接受Func<Task>Func<Task<TResult>>形式的TaskFactory, 在这种情况下,只有在订阅了observable时才会创建和执行任务。

.ToObservable()需要已经创建(并因此启动)的任务。

答案 1 :(得分:7)

@Sickboy的回答是正确的。

  • Observable.FromAsync()将在订阅时启动任务。
  • Task.ToObservable()需要一个已在运行的任务。

Observable.FromAsync的一个用途是控制对异步方法的多次调用的重入。

这是两个方法不等同的例子:

//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)

请注意,在第一个示例中,可能需要使用ObserveOn()ObserveOnDispatcher()方法来确保action在原始调度程序上执行,因为Observable.FromAsync没有'等待任务,因此继续在任何可用的调度程序上执行

答案 2 :(得分:5)

查看代码,setInterval(f(){})调用Observable.FromAsync *似乎(至少在某些流程中)。我确信它们应该在语义上等效(假设您传递相同的参数,例如Scheduler,CancellationToken等)。

一个更适合链接/流利语法,可以单独阅读。无论你喜欢什么样的风格。

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

答案 3 :(得分:0)

除了能够使用CancellationToken之外,FromAsync还会延迟包含,因此这允许根据订阅时的条件更改任务逻辑。请注意,将不会启动任务,内部task.ToObservable将被调用。 Func确实允许您在创建任务时启动任务。