Reputation: 2946
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?
Upvotes: 1
Views: 233
Reputation: 6882
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);
}
Upvotes: 1