我正在考虑使用IObservable
在ac#async
方法中的请求 - 响应环境中获取响应并替换一些旧的基于回调的代码,但我发现如果推送了一个值(Subject.OnNext
)对于可观察但FirstAsync
还没有等待,那么FirstAsync
永远不会得到该消息。
有没有直接的方法让它工作,没有第二个任务/线程加同步?
public async Task<ResponseMessage> Send(RequestMessage message)
{
var id = Guid.NewGuid();
var ret = Inbound.FirstAsync((x) => x.id == id).Timeout(timeout); // Never even gets invoked if response is too fast
await DoSendMessage(id, message);
return await ret; // Will sometimes miss the event/message
}
// somewhere else reading the socket in a loop
// may or may not be the thread calling Send
Inbound = subject.AsObservable();
while (cond)
{
...
subject.OnNext(message);
}
在我发送请求之前,我无法将await
放到FirstAsync
,因为这会阻止请求被发送。
答案 0 :(得分:1)
await
将订阅观察者。您可以通过调用await
:
ToTask
分开
public async Task<ResponseMessage> Send(RequestMessage message)
{
var id = Guid.NewGuid();
var ret = Inbound.FirstAsync((x) => x.id == id).Timeout(timeout).ToTask();
await DoSendMessage(id, message);
return await ret;
}
答案 1 :(得分:1)
我仔细研究了一下,通过将热转换为冷可观察性,可以很容易地解决您的问题。将Subject
替换为ReplaySubject
。以下是文章:http://www.introtorx.com/content/v1.0.10621.0/14_HotAndColdObservables.html。
以下是解释:
Replay扩展方法允许您获取现有的observable 序列并根据ReplaySubject给它'重放'语义。作为一个 提醒一下,ReplaySubject将缓存所有值,以便任何迟到 订阅者也将获得所有价值。