首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ConfigureAwait for IObservable<T>

ConfigureAwait for IObservable<T>
EN

Stack Overflow用户
提问于 2015-05-15 14:19:14
回答 2查看 1K关注 0票数 0

当我在Task.Wait()中使用阻塞代码时,在等待Rx查询的async方法时,我遇到了一个死锁。

这就是一个例子:

代码语言:javascript
复制
public void BlockingCode() 

{

    this.ExecuteAsync().Wait();

}

public async Task ExecuteAsync() 

{

    await this.service.GetFooAsync().ConfigureAwait(false);

    //This is the RX query that doesn't support ConfigureAwaitawait 
    await this.service.Receiver
      .FirstOrDefaultAsync(x => x == "foo")
      .Timeout(TimeSpan.FromSeconds(1));

}

因此,我的问题是,在可访问的ConfigureAwait上是否有任何等价的IObservable来确保在同一个SynchronizationContext上不恢复延续。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-05-17 17:55:34

你必须理解“等待观察”意味着什么。看看。所以,在语义上,您的代码

代码语言:javascript
复制
await this.service.Receiver
    .FirstOrDefaultAsync(x => x == "foo")
    .Timeout(TimeSpan.FromSeconds(1));

等于

代码语言:javascript
复制
await this.service.Receiver
    .FirstOrDefaultAsync(x => x == "foo")
    .Timeout(TimeSpan.FromSeconds(1))
    .LastAsync()
    .ToTask();

(请注意,这里存在某种冗余,调用FirstOrDefaultAsyncLastAsync,但这不是问题)。

因此,您就可以完成任务(如果可用的话,还可以增加一个CancellationToken )。您现在可以使用ConfigureAwait了。

票数 5
EN

Stack Overflow用户

发布于 2015-05-15 17:57:50

ConfigureAwait与服务生本身没有直接关系,相反,它是TPL的一个功能,可以配置Task应该如何完成。这是有问题的,因为这个TPL方法不返回一个新的Task,所以您不能将它转换成可观察的Task

Rx本身基本上是自由线程的。您可以使用比Tasks更精细的控件来控制订阅和事件期间使用的线程-有关以下内容的更多信息:ObserveOn和SubscribeOn -正在做工作的地方

很难修复您的代码,因为您没有提供一个小型但完整的工作示例--但是,Rx中内置的函数不会尝试将其配置到特定的线程,除非您特别告诉它们使用上面的操作符之一。

如果将像Observable.FromAsync这样的运算符组合起来,将Task转换为可观察的,则可以使用Observable.SubscribeOn(Scheduler.Default)从当前SynchronizationContext启动Task

下面是一个可玩的要点(为LINQPad设计,使用nuget包rx运行):https://gist.github.com/james-world/82c3cc39babab7870f6d

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30261847

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档