2010-12-10 41 views
1

Je commence avec System.Reactive et aimant la simplicité mais je suis venu contre quelque chose qui semble elle doit avoir une solution élégante mais je ne suis pas créer quelque chose comme un solution élégante !!Comment gérer un délai d'attente de Webservice dans System.Reactive

Le scénario est que je veux partir à un service Web 3ème partie pour obtenir des informations (dans un thread séparé) et à la recherche de temps localement. Puis fusionner les résultats les temps à moins que WebService dehors et je ne prendrai que les informations à partir des résultats locaux.

Je veux donc d'introduire un délai d'attente à la section Observable ici:

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

Tout le monde fait quelque chose de semblable? Il semble que ce doit être une chose assez courante de le faire, à savoir si le 3e temps d'appel du parti font sur X?

Répondre

4

Quelle que soit la façon dont vous voulez voulez que le délai d'attente de se produire (Rx contrôlé ou proxy client), vous voulez probablement utiliser 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; 
    } 
} 

Si vous voulez utiliser le délai d'attente de votre webservice, juste attraper cette exception tapez plutôt.

+0

Merci Richard, semble être une bonne solution. Je vais vérifier demain matin! – ArtificialGold

+1

Pas problemss. Je viens de remarquer que vous utilisez .NET 3.5 et que vous n'avez donc pas de covariance. Pour contourner cela, j'ai ajouté une distribution à l'appel 'Observable.Return'. –