2017-01-09 105 views
2

目前我使用這個代碼,以獲取文件:下載文件

WebClient webClient = new WebClient(); 
webClient.DownloadProgressChanged += webClient_DownloadProgressChanged; 
webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(webClient_ProgressCompleted); 

我爲了弄清楚如何把這個一直走在文檔看看使用Rx編碼。

我已經開始使用FromEvent創建Observable以注意DownloadFileCompleted事件。

Observable.FromEvent<?>(?, ?) 

不過,我無法計算如何填寫這些?

有人能給我一個例子嗎?

到現在爲止,我已經試過:

Observable.FromEvent<AsyncCompletedEventArgs>(?1:addHandler, ?2:removeHandler). 

儘管如此,.NET是請求我?1:addHandler?2:removeHandlerAction<Action<AsyncCompletedEventArgs>>(那是什麼)?

+0

爲什麼你需要RX在這裏? – tym32167

+5

我們要使用'Rx'。 – Jordi

+1

@ tym32167,Rx是關於作曲。似乎Jordi正在尋找創建一個可能最終成爲Rx管道的構建模塊之一。 –

回答

9

這些重載是如此棘手,我必須look them up every time。我已經包括了一些樣本,申購代碼,讓你開始:

WebClient webClient = new WebClient(); 
var progressChangedObservable = Observable.FromEventPattern<DownloadProgressChangedEventHandler, DownloadProgressChangedEventArgs>(
    h => webClient.DownloadProgressChanged += h, 
    h => webClient.DownloadProgressChanged -= h 
); 

var downloadCompletedObservable = Observable.FromEventPattern<AsyncCompletedEventHandler, AsyncCompletedEventArgs>(
    h => webClient.DownloadFileCompleted += h, 
    h => webClient.DownloadFileCompleted -= h 
); 

progressChangedObservable 
    .Select(ep => ep.EventArgs) 
    .Subscribe(dpcea => Console.WriteLine($"{dpcea.ProgressPercentage}% complete. {dpcea.BytesReceived} bytes received. {dpcea.TotalBytesToReceive} bytes to receive.")); 

downloadCompletedObservable 
    .Select(ep => ep.EventArgs) 
    .Subscribe(_ => Console.WriteLine("Download file complete.")); 

var dummyDownloadPath = @"C:\temp\temp.txt"; 
webClient.DownloadFileAsync(new Uri(@"http://google.com"), dummyDownloadPath); 

編輯:

每@ Enigmativity的建議,這是可以做到所有這些代碼在功能風格,也處理清理所有IDisposable s。但是,我不覺得它是可讀的,因此不會推薦它:

Observable.Using(() => 
    { 
     var webClient = new WebClient(); 
     webClient.Headers.Add("User-Agent: Other"); 
     return webClient; 
    }, webClient => 
    Observable.Using(() => 
     Observable.FromEventPattern<DownloadProgressChangedEventHandler, DownloadProgressChangedEventArgs>(
       h => webClient.DownloadProgressChanged += h, 
       h => webClient.DownloadProgressChanged -= h 
      ) 
      .Select(ep => ep.EventArgs) 
      .Subscribe(dpcea => Console.WriteLine($"{dpcea.ProgressPercentage}% complete. {dpcea.BytesReceived} bytes received. {dpcea.TotalBytesToReceive} bytes to receive.")), 
     sub1 => Observable.Using(() => 
      Observable.FromEventPattern<AsyncCompletedEventHandler, AsyncCompletedEventArgs>(
        h => webClient.DownloadFileCompleted += h, 
        h => webClient.DownloadFileCompleted -= h 
       ) 
       .Select(ep => ep.EventArgs) 
       .Subscribe(_ => Console.WriteLine("Download file complete.")), 
      sub2 => webClient.DownloadFileTaskAsync(new Uri(@"http://google.com"), @"C:\temp\temp.txt").ToObservable() 
     ) 
    ) 
) 
    .Subscribe(_ => {}); //Subscription required to trigger nested observables 
+0

謝謝@Shlomo。然而,我不太想弄清楚如何使用'WebClient wc'來使用每個observable ...你可以添加一些幫助的東西代碼嗎? – Jordi

+0

添加了一些示例訂閱。 – Shlomo

+2

我寫了這本書,我也必須每次都查閱它們。然而,對於快速入侵,優秀的'Observable.Create'可以更容易使用。 –