使用反应性观察取消下载

时间:2017-01-11 16:39:36

标签: .net system.reactive

我创建了这个方法,以便从事件中创建Observable。我正在尝试下载文件,并更新进度条:

private void BuildObservables(WebClient webClient)
{
    Observable.FromEventPattern<AsyncCompletedEventHandler, AsyncCompletedEventArgs>(h => webClient.DownloadFileCompleted += h, h => webClient.DownloadFileCompleted -= h)
        .Select(ep => ep.EventArgs)
        .Subscribe(
            a =>
            {
                this.WizardViewModel.PageCompleted()
            },
        );

    Observable.FromEventPattern<DownloadProgressChangedEventHandler, DownloadProgressChangedEventArgs>(h => webClient.DownloadProgressChanged += h, h => webClient.DownloadProgressChanged -= h)
        .Select(ep => ep.EventArgs)
        .Subscribe(
            a =>
            {
                this.progressEdit.Position = a.ProgressPercentage;
                progressEdit.Update();
            }
        );
}

然而,当我下载开始时,我想提供一个用户按钮以取消下载过程。

如何根据此代码添加此取消?

1 个答案:

答案 0 :(得分:1)

WebClient有一个CancelAsync方法,可以完成这项工作。

就Rx而言,您无法取消下载,但您可以处置订阅,这实际上意味着无视未来的更新:

async Task Main()
{
    var webClient = new WebClient();
    var dummyDownloadPath = @"C:\temp\temp.txt";
    var disposable = BuildObservables(webClient);
    webClient.DownloadFileAsync(new Uri(@"http://google.com"), dummyDownloadPath);
    await Task.Delay(TimeSpan.FromMilliseconds(100));
    disposable.Dispose();
}
private IDisposable BuildObservables(WebClient webClient)
{
    var downloadSubscription = Observable.FromEventPattern<AsyncCompletedEventHandler, AsyncCompletedEventArgs>(
        h => webClient.DownloadFileCompleted += h, 
        h => webClient.DownloadFileCompleted -= h
    )
        .Select(ep => ep.EventArgs)
        .Subscribe(
            a =>
            {
                Console.WriteLine("Download completed.");
//              this.WizardViewModel.PageCompleted()
            }
        );

    var progressSubscription = Observable.FromEventPattern<DownloadProgressChangedEventHandler, DownloadProgressChangedEventArgs>(
            h => webClient.DownloadProgressChanged += h, 
            h => webClient.DownloadProgressChanged -= h
        )
        .Select(ep => ep.EventArgs)
        .Subscribe(
            a =>
            {
                Console.WriteLine("Download Percent complete:" + a.ProgressPercentage);
                //              this.progressEdit.Position = a.ProgressPercentage;
                //              progressEdit.Update();
            }
        );
        return new CompositeDisposable(downloadSubscription, progressSubscription);
}