2012-04-26 22 views
3

什麼是安全取消DownloadFileAsync操作的最佳方法?中止WebClient.DownloadFileAsync操作

我有一個線程(後臺工作人員),它啓動下載並管理其他方面,並且當我看到線程已經結束時結束CancellationPending == true.啓動下載後,線程將靜止並旋轉,直到下載已完成,或線程被取消。

如果線程被取消,我想取消下載。這樣做有一個標準的習慣用法嗎?我試過CancelAsync,但我得到一個WebException(中止)。我不確定這是否是一種乾淨的取消方式。

謝謝。

編輯:第一異常是與設置爲一個在內部流對象(調用堆棧):

System.dll中System.Net.Sockets.NetworkStream.EndRead(System.IAsyncResult asyncResult) 系統.dll!System.Net.PooledStream.EndRead(System.IAsyncResult asyncResult)

回答

6

我不知道爲什麼你會從調用CancelAsync中得到異常。

我使用WebClient處理當前項目中的並列下載,並且在調用CancelAsync時,由WebClient引發事件DownloadFileCompleted,其中屬性Cancelled爲真。我的事件處理程序是這樣的:

private void OnDownloadFileCompleted(object sender, AsyncCompletedEventArgs e) 
{ 
    if (e.Cancelled) 
    { 
     this.CleanUp(); // Method that disposes the client and unhooks events 
     return; 
    } 

    if (e.Error != null) // We have an error! Retry a few times, then abort. 
    { 
     if (this.retryCount < RetryMaxCount) 
     { 
      this.retryCount++; 
      this.CleanUp(); 
      this.Start(); 
     } 

     // The re-tries have failed, abort download. 
     this.CleanUp(); 
     this.errorMessage = "Downloading " + this.fileName + " failed."; 
     this.RaisePropertyChanged("ErrorMessage"); 
     return; 
    } 

    this.message = "Downloading " + this.fileName + " complete!"; 
    this.RaisePropertyChanged("Message"); 

    this.progress = 0; 

    this.CleanUp(); 
    this.RaisePropertyChanged("DownloadCompleted"); 
} 

與所述消除方法很簡單:

/// <summary> 
/// If downloading, cancels a download in progress. 
/// </summary> 
public virtual void Cancel() 
{ 
    if (this.client != null) 
    { 
     this.client.CancelAsync(); 
    } 
} 
+0

感謝。我已經更新了問題以顯示我正在獲取的內容(現在,我首先獲得了一個對象處置異常,似乎來自底層流)。也許我是在等待完成取消?我會調查。 – Robinson 2012-04-26 12:42:20

+0

@Robinson也許這可能會引起人們的興趣:「如果文件足夠快地下載進度變化事件仍然​​在關閉文件之後,WebClient就會拋出,捕獲並忽略Object Disposed異常。」 (參考:http://stackoverflow.com/questions/3169749/system-net-webclient-cancelasync-throws-objectdisposedexception-cannot-acces) – 2012-04-26 12:56:29

+0

@Robinson你也應該注意到CancelAsync並不立即取消下載,所以如果你例如過早地處理對象,他們可能會得到一個Object Disposed異常,因爲該進程還沒有被取消。 – 2012-04-26 13:00:55