开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜