Search code examples
c#.netasync-awaitreactive-programmingsystem.reactive

Executing a synchornous method, but with a timeout, using System.Reactive


What's the correct way to call the Read method with a timeout?

public int Method()
{
       return Read();
}

I've tried with this, but my application is shutting down completely when a timeout happens, so I guess there's something wrong with it.

public int Method() 
{
     return Observable.Start(() => Read()).Timeout(TimeSpan.FromSeconds(2)).Wait();
}

Solution

  • You should avoid using Timeout as it does control by exception, which we know is bad.

    I tend to use this pattern:

    Observable
        .Amb(
            Observable.Timer(TimeSpan.FromSeconds(2.0)).Select(x => (int?)null),
            Observable.Start(() => (int?)Read()))
    

    Amb fires on the first observable to produce a value and then ignores the other. Just set an appropriate return value and in your case it's int? to allow the number to come through or a null if it times out.

    I then use the fact that we can await the last value of an observable and I do this:

    public async Task<int?> Method() =>
        await
            Observable
                .Amb(
                    Observable.Timer(TimeSpan.FromSeconds(2.0)).Select(x => (int?)null),
                    Observable.Start(() => (int?)Read()))
                .LastAsync();
    

    If you don't want to use tasks then you can still use Wait():

    public int? Method() =>
        Observable
            .Amb(
                Observable.Timer(TimeSpan.FromSeconds(2.0)).Select(x => (int?)null),
                Observable.Start(() => (int?)Read()))
            .Wait();