Как управлять таймаутом веб-сервиса в System.Reactive - PullRequest
1 голос
/ 10 декабря 2010

Я начинаю с System.Reactive и мне нравится его простота, но я столкнулся с чем-то, что, кажется, должно иметь элегантное решение, но я не создаю ничего похожего на элегантное решение !!

Сценарий состоит в том, что я хочу перейти на сторонний веб-сервис, чтобы получить некоторую информацию (в отдельном потоке) и в то же время искать локально.Затем объедините результаты, ЕСЛИ не истечет время ожидания веб-службы, и я возьму только информацию из локальных результатов.

Поэтому я хочу ввести здесь тайм-аут для наблюдаемого раздела:

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 Ответ

4 голосов
/ 11 декабря 2010

Независимо от того, как вы хотите, чтобы истекло время ожидания (контролируемый 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;
    }
}

Если вы хотите использовать тайм-аут вашего веб-сервиса, просто перехватите этот тип исключения.

...