Reputation: 972
I'm new to using event handlers and backgroundworkers, so I may be missing something completely obvious here. Still, I've been trying to fix this for two days, so I thought I might as well see what anyone had to say.
I have a backgroundworker called SqlExpressDownloader. It starts running at the beginning of my program, the rest of the work runs, and then it should wait for the operations in the SqlExpressDownloader_DoWork()
method to complete before continuing. The only problem is that for some reason whenever I do while(SqlExpressDownloader.IsBusy)
, it always responds as busy and therefore will wait forever.
The code for the event handler is here:
private void SqlExpressDownloader_DoWork(object sender, DoWorkEventArgs e)
{
string sSource = string.Format("{0}\\{1}", Paths.Settings_Common, "sqlexpr_x64_enu.exe");
Debug.WriteLine(sSource);
Debug.WriteLine("http://www.elexioamp.com/Install/redistributables/sql2008r2express/sqlexpr_x64_enu.exe");
if (!System.IO.File.Exists(sSource))
{
WebClient oWebClient = new WebClient();
oWebClient.DownloadProgressChanged += DownloadProgressChanged;
oWebClient.DownloadDataCompleted += DownloadComplete;
oWebClient.DownloadFileAsync(new System.Uri("http://www.elexioamp.com/Install/redistributables/sql2008r2express/sqlexpr_x64_enu.exe"), sSource);
while (oWebClient.IsBusy)
{
Thread.Sleep(100);
}
e.Result = "";
DownloadFinished = true;
}
}
I have watched the code and have watched it complete this method. I even added a return
after the DownloadFinished = true
, but it still responds as busy. What I want to know is how to make the backgroundworker respond as not busy.
EDIT The events are all added in the constructor as shown here:
SqlExpressDownloader = new BackgroundWorker();
SqlExpressDownloader.DoWork += new DoWorkEventHandler(this.SqlExpressDownloader_DoWork);
SqlExpressDownloader.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.SqlExpressDownloader_RunWorkerCompleted);
The RunWorkerCompleteEventHandler
looks like this:
private void SqlExpressDownloader_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
Debug.WriteLine("The actions are complete.");
}
else
{
Debug.WriteLine("Error in completed work.");
}
}
But, when I debugged it last, it didn't actually trigger.
Upvotes: 5
Views: 2472
Reputation: 1134
I had a similar issue. DownloadASync would fire but .IsBusy would always stay on true.
This probably won't be a common problem, just thought I share my resolution.
I used
MessageBox.Show(new Form() { TopMost = true }, "", "")
This was the cause. I also tried:
var t = new Form() { TopMost = true };
MessageBox.Show(t, "", "");
t.Dispose();
This caused the same issue.
My code had multiple threads, I assume one of them must have gotten stuck, or perhaps the MessageBox(the new Form() { TopMost = true; } ) call created a stuck thread.
As soon as I removed that part, eg.
MessageBox.Show("", "");
Everything worked as expected again.
So maybe you are creating another thread somewhere that is causing your issue.
Upvotes: 1
Reputation: 66439
Instead of querying SqlExpressDownloader.IsBusy
in a loop, try subscribing to the RunWorkerCompleted
event of the BackgroundWorker
and place your code in there that should only occur after the DoWork
event has completed.
You'll also have access to the RunWorkerCompletedEventArgs
, which you can check to make sure no error was thrown from the DoWork
portion of your BackgroundWorker
.
...
...
SqlExpressDownloader.RunWorkerCompleted += SqlExpressDownloader_RunWorkerCompleted;
SqlExpressDownloader.RunWorkerAsync();
}
private void SqlExpressDownloader_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
// do something in response to the error
}
// stuff to do after DoWork has completed
}
I found Joe Albahari's tutorial helpful when I was learning how to use these.
Upvotes: 3
Reputation: 1221
You can replace your code with more elegant async/await solution like this
private async Task SqlExpressDownloadAsync()
{
string sSource = string.Format("{0}\\{1}", Paths.Settings_Common, "sqlexpr_x64_enu.exe");
Debug.WriteLine(sSource);
Debug.WriteLine("http://www.elexioamp.com/Install/redistributables/sql2008r2express/sqlexpr_x64_enu.exe");
if (!System.IO.File.Exists(sSource))
{
WebClient oWebClient = new WebClient();
oWebClient.DownloadProgressChanged += DownloadProgressChanged;
oWebClient.DownloadDataCompleted += DownloadComplete;
await oWebClient.DownloadFileTaskAsync(new System.Uri("http://www.elexioamp.com/Install/redistributables/sql2008r2express/sqlexpr_x64_enu.exe"), sSource);
}
}
Upvotes: 1