2010-12-10 5 views
1

Ich fange mit System.Reactive an und liebe die Einfachheit davon, aber ich bin auf etwas gestoßen, das scheint, muss es eine elegante Lösung haben, aber ich erschaffe nichts wie ein elegante Lösung !!Wie man ein Webservice Timeout in System.Reactive verwaltet

Das Szenario ist, dass ich zu einem 3rd-Party-Web-Service gehen möchte, um einige Informationen (in einem separaten Thread) zu erhalten und gleichzeitig lokal zu suchen. Dann füge die Ergebnisse zusammen, OHNE dass der Webservice abgelaufen ist, und ich werde nur die Informationen aus den lokalen Ergebnissen übernehmen.

Deshalb möchte ich hier ein Timeout zu den beobachtbaren Abschnitt vorstellen:

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

Jeder getan etwas ähnliches? Es scheint, dass es eine ziemlich übliche Sache sein muss, zu tun, d. H., Wenn der Anruf des Drittanbieters das Zeitlimit überschreitet, X?

Antwort

4

Egal, wie Sie wollen das Timeout erfolgen soll (Rx gesteuert oder Client-Proxy), möchten Sie wahrscheinlich Catch verwenden:

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

Wenn Sie Ihren Webservice des Timeout verwenden möchten, fangen gerade diese Ausnahme Geben Sie stattdessen ein.

+0

Danke Richard, sieht aus wie eine gute Lösung. Ich werde es morgen früh überprüfen! – ArtificialGold

+1

Kein Problem. Ich habe gerade bemerkt, dass Sie .NET 3.5 verwenden und daher keine Kovarianz haben. Um das zu umgehen, habe ich einen Cast zum Aufruf "Observable.Return" hinzugefügt. –

Verwandte Themen