简体   繁体   English

downloader.DownloadFileTaskAsync 下载第一个文件后卡住

[英]downloader.DownloadFileTaskAsync stuck after downloading the first file

I am using downloader我正在使用下载

My code is我的代码是

    public DownloadWindow()
    {
        InitializeComponent();
        StartDownloading();
    }

    private async void StartDownloading()
    {
            var downloader = new DownloadService(downloadOpt);
            downloader.DownloadProgressChanged += OnDownloadProgressChanged;

            await downloader.DownloadFileTaskAsync(url1, file1);
            await downloader.DownloadFileTaskAsync(url2, file2);
    }

    private void OnDownloadProgressChanged(object sender, Downloader.DownloadProgressChangedEventArgs e)
    {
        try
        {
             this.Dispatcher.Invoke(new Action(() =>
            {

             downloadProgressBar.Value = e.ProgressPercentage;
            
            }));
        }
        catch { }
    }

The first file is downloaded and it gets stuck at the second file.第一个文件被下载并卡在第二个文件上。

If I comment out the first download, the second file is downloaded just fine.如果我注释掉第一个下载,第二个文件下载就好了。

Creating another downloader object also doesn't help创建另一个下载器 object 也无济于事

What am I doing wrong?我究竟做错了什么?

The root cause is a deadlock.根本原因是死锁。 Two methods are trying to gain access to the main UI thread using the Windows message queue without giving each other a chance to continue.有两种方法尝试使用 Windows 消息队列来访问主 UI 线程,而彼此没有机会继续。

Use BeginInvoke() instead of Invoke() for posting messages to avoid locking the UI thread in `OnDownloadProgressChanged.使用BeginInvoke()而不是Invoke()发布消息以避免将 UI 线程锁定在 `OnDownloadProgressChanged.

like so:像这样:

private void OnDownloadProgressChanged(object sender, Downloader.DownloadProgressChangedEventArgs e)
{
           this.Dispatcher.BeginInvoke(new Action(() =>
          {
               downloadProgressBar.Value = e.ProgressPercentage;
          }));
}

The code in StartDownloading() also has issues like using fire and forget async void for a long-running task. StartDownloading()中的代码也存在一些问题,例如对长时间运行的任务使用 fire 并忘记async void One would want to cancel it or wait until it is completed.人们会想要取消它或等到它完成。 Also it does not need to start from within the constructor, when the dialog's window is not fully constructed yet.此外,当对话框的 window 尚未完全构建时,它也不需要从构造函数中开始。


void StartDownloading()
{
   \\ Run download in a background thread 
   _downloadTask = Task.Run(()=>RunDownloading());
}

// Check the state of this task before closing the dialog.
Task _downloadTask;


async Task RunDownloading()
{
       var downloader = new DownloadService(downloadOpt);
       downloader.DownloadProgressChanged += OnDownloadProgressChanged;

       await downloader.DownloadFileTaskAsync(url1, file1);
       await downloader.DownloadFileTaskAsync(url2, file2);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM