简体   繁体   中英

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

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.

Use BeginInvoke() instead of Invoke() for posting messages to avoid locking the UI thread in `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. 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.


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);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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