如何在System.Reactive中管理Web服务超时

时间:2010-12-10 17:14:34

标签: .net-3.5 system.reactive

我开始使用System.Reactive并且喜欢它的简单性,但是我遇到了一些似乎必须有一个优雅解决方案的东西,但我并没有创造出类似优雅解决方案的东西!!

场景是我想去第三方网络服务获取一些信息(在一个单独的线程中),同时在本地搜索。然后合并结果除了Web服务超时,我将只获取本地结果的信息。

因此,我想在此处向Observable部分引入超时:

using System;
using System.Linq;
using System.Threading;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Starting");
            var o = Observable.Start(DoSeparateThreadCall);

            DoCallInThisThread();

            o.First();

            Console.WriteLine("the End");
            Console.ReadLine();
        }

        private static void DoSeparateThreadCall()
        {
            Console.WriteLine("Started in separate thread call");
            Thread.Sleep(3000);
            Console.WriteLine("Ended in separate thread call");
        }

        static void DoCallInThisThread()
        {
            Console.WriteLine("Started in this thread call");
            Thread.Sleep(2000);
            Console.WriteLine("Ended in this thread call");
        }
    }
}

有人做过类似的事吗?似乎它必须是一个相当普遍的事情,即如果第三方呼叫超时做X?

1 个答案:

答案 0 :(得分:4)

无论您希望如何发生超时(Rx控制或客户端代理),您可能希望使用Catch

public IObservable<IList<SearchResult>> GetSearchResults()
{
    return Observable.ForkJoin(
        GetRemoteSearchResults(),
        GetLocalSearchResults()
        )
        .Select(MergeSearchResults);
}

private IObservable<IList<SearchResult>> GetRemoteSearchResults()
{
    return GetSearchResultsFromWebService()
        .Timeout(RemoteTimeOut)
        .Catch<IList<SearchResult>, TimeoutException>(
            Observable.Return((IList<SearchResult>)new List<SearchResult>())
        );
}

private IObservable<IList<SearchResult>> MergeSearchResults(
    IList<SearchResult>[] allResults)
{
    var localResults = allResults[0];
    var remoteResults = allResults[1];

    if (remoteResults.Count == 0)
    {
        return localResults;
    }
    else
    {
        var mergedResults = new List<SearchResult>();
        // merge

        return mergedResults;
    }
}

如果要使用webservice的超时,只需捕获该异常类型。