2012-03-22 17 views
1

私はウェブからcsvファイルをダウンロードする機能を持っています。 2つのウェブサイトを1つずつ呼び出すように拡張する必要があります。しかし、私はそれを行う方法がわからないんだけど...Rx Observable - Chaining

相続機能です:

// 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... 
} 
+1

あなたのコードは不完全なようです。 'url1'と' url2'が入っていますが、 'url'で' OpenReadAsync'を呼び出します。あなたのコードの意図は不明です。この質問を改善していただけますか? – Enigmativity

+1

2つの観測点に2つのURLをマップし、観測可能なこれらの2つを連結して観測可能にし、 – Ankur

答えて

1

あなたは [OK]をする必要がありが何をしています。 2回目の電話をOpenReadAsyncにすると、2番目のイベントが発生し(URLごとに1つずつ)、そのサブスクリプションは両方を処理します。私はあなたはそれが適切に配置されたことがないです(WebClientとスコープの外に出ることを考えると、いくつかの寿命の問題を抱えていると思われる、しかし

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

あなたは、単に次の操作を行うことができるはずです)。

0

私は個人的にここで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; 
}