4

DownloadFileAsync 操作を安全にキャンセルする最善の方法は何ですか?

ダウンロードを開始し、その他の側面を管理するスレッド (バックグラウンド ワーカー) があり、スレッドがCancellationPending == true. ダウンロードを開始した後、ダウンロードが完了するまで、スレッドは座ってスピンします。スレッドはキャンセルされます。

スレッドがキャンセルされた場合、ダウンロードをキャンセルしたいです。これを行うための標準的なイディオムはありますか? を試しCancelAsyncましたが、そこから WebException が発生しました (中止されました)。これがキャンセルを行うクリーンな方法かどうかはわかりません。

ありがとう。

編集: 最初の例外は、オブジェクトが内部ストリーム (コール スタック) に配置されていることです。

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

4

1 に答える 1

7

CancelAsync の呼び出しで例外が発生する理由がわかりません。

WebClient を使用して、現在のプロジェクトで並列ダウンロードを処理しています。CancelAsync を呼び出すと、プロパティが trueDownloadFileCompletedの WebClient によってイベントが発生します。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();
    }
}
于 2012-04-26T11:59:20.287 に答える