• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2252
  • Last Modified:

backgroundworker.cancelasync always busy

hello all,

I have a wpf project, and on the timeconsuming processing, I run the method on a background worker.  like so

        public InternalLoginClass()
        {
                                    if (!backgroundWorkerTimeline.IsBusy)
                                    {
                                        object[] tempArguments = new object[3];
                                        tempArguments[0] = connString;
                                        tempArguments[1] = "FULL";
                                        tempArguments[2] = clientID;
                                        backgroundWorkerTimeline.RunWorkerAsync(tempArguments);
                                    }
}

Open in new window


then when user hits button I run

            //check for background workers to complete
            if (myInternalLoginClass.backgroundWorkerTimeline.IsBusy) myInternalLoginClass.backgroundWorkerTimeline.CancelAsync();
            while (myInternalLoginClass.backgroundWorkerTimeline.IsBusy)
            {
            }
***next line of code here

Open in new window


I was thinking that as long as I put in that continuous loop, while busy... do nothing,
the backgroundthread would run until finished, then since it was complete, it would hit ***next line of code here.

but when I try this the loop never exits... the workers stays in IsBusy.

Am I thinking about this the wrong way?  Even when I hit cancelasync and check in the background thread... it stays ISBUSY?

any ideas?
0
solarissf
Asked:
solarissf
4 Solutions
 
ktaczalaCommented:
add this to your loop: Application.DoEvents();
0
 
Jacques Bourgeois (James Burger)PresidentCommented:
ktaczala suggestion would most probably work in a Windows Forms application, but I do not think that it is available in a WPF application. From what I have read, the BackgroundWorker happens to be its replacement.

I haven't worked much with the BackgroundWorker, so I might be in the clouds here, but if you look at the documentation for CancelAsync, it says:

CancelAsync submits a request to terminate the pending background operation and sets the CancellationPending property to true.

When you call CancelAsync, your worker method has an opportunity to stop its execution and exit. The worker code should periodically check the CancellationPending property to see if it has been set to true.


My understanding of this is that CancelAsync does not stop the BackgroundWorker. It's up to the worker code to terminate itself.

There might also be another problem that you will encounter down the line. The code is optimized when it is compiled. This does not happens in Debug mode, debugger would be fooled if it tried to work with source code and compiled code that do not match. So you see your loop when you debug.

But a loop that does nothing is a very good candidate for the optimizer. It could well be removed in the Release version. If you have problems because ***next line of code here seems to execute before the worker has finished it's job, add some significant code inside the loop to prevent the optimizer from removing it. Simply declaring a variable that does nothing is not enough, because the optimizer will probably remove that also.
0
 
Naman GoelSoftware engineer 1Commented:
Agree with JamesBurger, BackgroundWorker class is just a wrapper for a thread running in background with some or the events to be triggered for reporting progress of job as well as completion of job, Cancelling a Thread is not at all possible, so user have to code and place a logic to cancel the job as the code will get cancellation signal.

For example, if your form class you can cancel a running BackgroundWorker object as follows:

backgroundWorker.CancelAsync();

Open in new window


Your DoWork event handler has to test for cancellation similar to:

static void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
  BackgroundWorker backgroundWorker = sender as BackgroundWorker;
  if(backgroundWorker != null)
  {
    backgroundWorker.ReportProgress(0); // report start

    int percentProgress = 1;
    while(!backgroundWorker.CancellationPending)
    {
      // TODO: Unit of work.
      // TODO: update percentProgress
      backgroundWorker.ReportProgress(precentProgress);
    }
    // TODO: update e.Result with result, if required.

    // provide feedback to the other thread that the
    // cancellation was processed
    if(backgroundWorker.CancellationPending)
    {
      e.Cancel = true;
    }
    else
    {
      // report end of processing
      backgroundWorker.ReportProgress(100);
    }
  }
}

Open in new window


The above code assumes the following was executed before the RunWorkerAsync call:

backgroundWorker.WorkerReportsProgress = true;
backgroundWorker.WorkerSupportsCancellation = true;

Open in new window

0
 
solarissfAuthor Commented:
thanks everyone.  So I agree, when you run .cancel, you then have to check for that flag of cancellation pending.  I've done that successfully, after further research I found online that my worker was always locked as busy.  Found this was due to my loop locking the thread not being able to send a signal to make worker UNBUSY.  (at least I read this on this internet... and if its on the internet is HAS to be true)

I had to put this in the middle of my loop while waiting for worker to finish.

        public static void DoEvents()
        {
            Application.Current.Dispatcher.Invoke(DispatcherPriority.Background,
                                                  new Action(delegate { }));
        }

Open in new window


Seems to be working for now, guess we'll see if this is a real solution.

Thanks again!
0
 
solarissfAuthor Commented:
added details in my response for solution
0

Featured Post

The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now