The background worker is always busy.

I am new to using event handlers and background workers, so it may be something completely obvious to me here. However, I tried to fix this for two days, so I thought that I could also see what someone had to say.

I have a desktop called SqlExpressDownloader. It starts at the beginning of my program, the rest of the work is done, and then it must wait for the operations in the SqlExpressDownloader_DoWork() method to SqlExpressDownloader_DoWork() before continuing. The only problem is that for some reason, when I do while(SqlExpressDownloader.IsBusy) , it always reacts as busy and therefore will always wait.

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 looked at the code and watched it complete this method. I even added return after DownloadFinished = true , but it still reacts as busy. I want to know how to make a background worker react like not busy.

EDIT All events are added to the constructor, as shown below:

  SqlExpressDownloader = new BackgroundWorker(); SqlExpressDownloader.DoWork += new DoWorkEventHandler(this.SqlExpressDownloader_DoWork); SqlExpressDownloader.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.SqlExpressDownloader_RunWorkerCompleted); 

RunWorkerCompleteEventHandler as follows:

  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 this last one, it didn’t actually cause it.

+4
source share
3 answers

You can replace your code with a more elegant async / wait 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); } } 
+1
source

Instead of requesting SqlExpressDownloader.IsBusy in a loop, try subscribing to the RunWorkerCompleted BackgroundWorker event and put your code there, which should only appear after the DoWork event DoWork .

You will also have access to RunWorkerCompletedEventArgs , which you can check to make sure that no errors were made from the DoWork part 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 the Joe Albahari tutorial when I learned to use them.

+3
source

I had a similar problem. DownloadASync will work, but .IsBusy will always remain true.

This probably won't be a common problem, just think that I share my resolution.

I used

 MessageBox.Show(new Form() { TopMost = true }, "", "") 

That was the reason. I also tried:

 var t = new Form() { TopMost = true }; MessageBox.Show(t, "", ""); t.Dispose(); 

This caused the same problem.

There were several threads in my code, I assume that one of them should be stuck, or maybe MessageBox (a new call to Form () {TopMost = true;}) created a stuck thread.

As soon as I delete this part, for example.

 MessageBox.Show("", ""); 

Everything worked again as expected.

So, maybe you are creating another thread that is causing your problem.

+1
source

Source: https://habr.com/ru/post/1490926/


All Articles