2010-12-10 68 views
1

我刚开始使用System.Reactive并且非常喜欢它的简单性,但是我遇到了似乎它必须有一个优雅的解决方案的东西,但我没有创建任何类似于雅致的解决如何在System.Reactive中管理Webservice超时

这种情况是,我想去第三方Web服务获取一些信息(在一个单独的线程中),同时在本地进行搜索。然后合并结果,除非Web服务超时,我将仅从本地结果中获取信息。

所以我想介绍一个超时可观察的部分在这里:

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?

回答

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; 
    } 
} 

如果你想使用你的Web服务的超时,只捕获了异常改为输入。

+0

谢谢理查德,看起来像一个很好的解决方案。我明天早上会检查一下! – ArtificialGold 2010-12-12 21:02:59

+1

没问题。我只注意到你正在使用.NET 3.5,所以没有协变。为了解决这个问题,我在'Observable.Return'调用中添加了一个表演。 – 2010-12-12 21:12:11