Наблюдаемый Rx - Цепочка - PullRequest
       36

Наблюдаемый Rx - Цепочка

1 голос
/ 23 марта 2012

У меня есть функция, которая загружает CSV-файл из Интернета. Мне нужно расширить его так, чтобы он делал 2 звонка на 2 сайта один за другим. Однако я не уверен, как это сделать ...

Вот функция:

// Define other methods and classes here
private void GetCSVData(string url1, string url2)
{
    WebClient webClient = null;
    try
    {
        webClient = new WebClient();

        var task = Observable.FromEventPattern
            <OpenReadCompletedEventHandler, OpenReadCompletedEventArgs>
        (
            ev => webClient.OpenReadCompleted += ev,
            ev => webClient.OpenReadCompleted -= ev
        );

        // needs to be redone
        task.Subscribe(t => ParseCSV1(t.EventArgs.Result));

        // call ParseCSV1()
        // then call ParseCSV2()

        // needs redone, 2 calls to 2 website
        webClient.OpenReadAsync(new Uri(url1));     
    }
    catch (WebException wex)
    {
        System.Diagnostics.Debug.WriteLine(wex.ToString());
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine(ex.ToString());
    }
}

private void ParseCSV1(Stream stream)
{
    // Parse steps...
}

private void ParseCSV2(Stream stream)
{
    // Parse steps...
}

Ответы [ 2 ]

1 голос
/ 12 октября 2012

То, что у вас есть должно быть в порядке.Если вы сделаете второй вызов OpenReadAsync, то сработает второе событие (по одному для каждого URL), и ваша подписка обработает оба.

Вы должны просто иметь возможность выполнитьследующее:

// Call both, will generate two events.
webClient.OpenReadAsync(new Uri(url1));
webClient.OpenReadAsync(new Uri(url2));

Тем не менее, я подозреваю, что у вас есть некоторые проблемы со сроком службы, учитывая, что вы выходите за рамки с WebClient (он никогда не удаляется должным образом)

0 голосов
/ 21 ноября 2012

Я ... лично я бы не использовал здесь Rx, наверное. На самом деле это звучит более подходящим для библиотеки задач; вот что-то вроде того, что я, вероятно, сделаю:

void Main()
{
    var webClient = new System.Net.WebClient();

    Task.Factory
        .StartNew(() => GetUrl("http://www.google.com"))
        .ContinueWith(tsk => ParseCsv(CheckAndHandleError(tsk)))
        .ContinueWith(tsk => 
            { 
                if(CheckAndHandleError(tsk)) 
                    return GetUrl("http://www.yahoo.com"); 
                else
                    return string.Empty;
            })
        .ContinueWith(tsk => ParseCsv(CheckAndHandleError(tsk)));

}

private T CheckAndHandleError<T>(Task<T> task)
{
    if(task.IsFaulted)
    {
        // you'll need to handle the tsk.Exception here
        throw new NotImplementedException();
    }
    else
    {
        return task.Result;
    }   
}

private string GetUrl(string address)
{
    using(var client = new WebClient())
    {
        var stream = client.OpenRead(address);
        using(var rdr = new StreamReader(stream))
        {
            return rdr.ReadToEnd();
        }
    }
}

private bool ParseCsv(string csvText)
{
    // whatever this is
    Console.WriteLine(csvText);
    return true;
}
...