2010-12-10 15 views
1

私はSystem.Reactiveから始めてシンプルなことを愛していますが、私はそれがエレガントな解決策を持たなければならないと思っていますが、エレガントなソリューション!System.ReactiveでWebサービスのタイムアウトを管理する方法

シナリオは、(別のスレッドで)いくつかの情報を取得し、同時にローカルで検索するためにサードパーティの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をタイムアウトする場合ですか?あなたのWebサービスのタイムアウトを使用したい場合は、単にその例外をキャッチし、

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

:関係なく、あなたは(Rxが制御またはクライアントプロキシ)が発生し、タイムアウトを行いたい場合どのように

答えて

4

は、おそらくCatchを使用したいです代わりにタイプします。

+0

ありがとうリチャード、良いソリューションのように見えます。私は明日の朝にそれを確認します! – ArtificialGold

+1

問題ありません。私はあなたが.NET 3.5を使用していることに気づいたので、共分散はありません。これを回避するために、Observable.Return'呼び出しにキャストを追加しました。 –

関連する問題