Using IObservable to implement an asynchronous method
Is it reasonable to use a method that returns IObservable to implement an alternative to the standard Begin/End asynchronous pattern? In the following code I'm wrapping a legacy API using Rx to provide a nicer interface to it.
The Messages
property on the API is a hot IObservable. My problem is that I think if I get the response message (i.e. m.RequestId == requestId
) before I return the IObservable
that filters responses, the subscriber will not see it and will not know that the operation completed.
Is there 开发者_如何学编程a way to do this properly?
public IObservable<bool> DoAsyncRequest()
{
Observable.Defer(delegate
{
int requestId = GenerateRequestId();
this.api.DoApiRequest(requestId);
return this.api.Messages
.Where(m => m.RequestId == requestId)
.Take(1)
.Timeout(DefaultTimeout);
});
}
Firstly it's absolutely fine to return an IObservable to implement asynchronous methods.
Secondly, if it's the DoApiRequest
method that kicks off the process that emits values through Messages
, you could subscribe to messages first before calling the method using CreateWithDisposable
public IObservable<bool> DoAsyncRequest()
{
return Observable.CreateWithDisposable<bool>(observer =>
{
var disposable = this.api.Messages
.Where(m => m.RequestId == requestId)
.Take(1)
.Timeout(DefaultTimeout);
.Subscribe(observer);
int requestId = GenerateRequestId();
this.api.DoApiRequest(requestId);
return disposable;
});
}
Alternatively, as you seem to have access to whatever class the api object is, you could also change DoApiRequest to return a cold observable i.e. possibly scrap the Messages property and instead return the IObservable on the DoApiRequest method.
Note
If I am correct in assuming that DoApiRequest method does kick off the process that emits values through Messages, then you're going to get odd results if this method is called multiple times. One call could get messages that were intended to be returned for another call. I would personally look into the alternative solution if you are able to.
精彩评论