当我尝试取消 DownloadFileTaskAsync 时,我的 WPF 应用程序崩溃并关闭

When I try to cancel DownloadFileTaskAsync my WPF application crash and shut down

我正在制作一个 WPF 应用程序,我在其中使用 WebClient 从网络服务器下载文件。当我下载文件时,当我试图取消下载时,我的 WPF 应用程序崩溃并关闭。这种情况并不总是发生。有时取消成功,但大多数情况下我不知道它的行为是这样的。谢谢

  public async Task DownloadProtocol(int torrentId, string address, string location)
    {
        Uri Uri = new Uri(address);
        try
        {
            using (client = new WebClient())
            {

                sw.Start();
                client.DownloadProgressChanged += (o, e) =>
                {
                    var thisGame = MainWindow._items.Find(item => item.Id == torrentId);
                    PercentageDone = (e.BytesReceived / TotalSize) * 100;

                    thisGame.Progress = (int)SizeReceived + (int)PercentageDone;

                    Console.Write("\r {0} ", PercentageDone);

                };

                client.DownloadFileCompleted += (o, e) =>
                {
                    if (e.Cancelled == true)
                    {
                        Console.WriteLine("Download has been canceled.");
                    }
                    else
                    {

                        Console.WriteLine("Download completed!");
                        SizeReceived += PercentageDone;
                    }

                    client.Dispose();
                };

                await client.DownloadFileTaskAsync(Uri, location);
            }
        }
        catch(WebException ex)
        {
            Log.Logger("Download error ", ex);
        }

    }  

取消功能:

    public void Cancel()
    {
        if(client != null)
        {
            client.CancelAsync();
        }
    }

WPF 应用程序通常会因为未处理的异常而崩溃。在 WPF 应用程序中,您可以通过在 App class 构造函数中订阅这些事件来记录 and/or 处理它们(请参阅下面的代码)。

您还应该从 DownloadFileCompleted 处理程序中删除 client.Dispose 调用,因为 client 将由 using 块处理,并且该实例可能尚未完成其他工作(例如,在调用处理程序之前发送任务完成)。

public partial class App : System.Windows.Application
{
    public App()
    {
        this.DispatcherUnhandledException += this.OnDispatcherUnhandledException;
        AppDomain.CurrentDomain.UnhandledException += this.OnAppDomainUnhandledException;
        System.Threading.Tasks.TaskScheduler.UnobservedTaskException += this.OnUnobservedTaskException;
    }

    private void OnAppDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        Log.Logger("AppDomainUnhandledException", e.ExceptionObject as Exception);
    }

    private void OnDispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
    {
        e.Handled = true;
        Log.Logger("DispatcherUnhandled: ", e.Exception);
    }

    private void OnUnobservedTaskException(object sender, System.Threading.Tasks.UnobservedTaskExceptionEventArgs e)
    {
        e.SetObserved();
        Log.Logger("UnobservedTaskException", e.Exception);
    }
}