Solved

backgroundworker.cancelasync always busy

Posted on 2014-01-10
5
1,774 Views
Last Modified: 2014-01-18
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
Comment
Question by:solarissf
5 Comments
 
LVL 12

Assisted Solution

by:ktaczala
ktaczala earned 167 total points
ID: 39772921
add this to your loop: Application.DoEvents();
0
 
LVL 40

Assisted Solution

by:Jacques Bourgeois (James Burger)
Jacques Bourgeois (James Burger) earned 166 total points
ID: 39773566
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
 
LVL 13

Accepted Solution

by:
Naman Goel earned 167 total points
ID: 39773618
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
 

Assisted Solution

by:solarissf
solarissf earned 0 total points
ID: 39776395
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
 

Author Closing Comment

by:solarissf
ID: 39790445
added details in my response for solution
0

Featured Post

3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
Performance in games development is paramount: every microsecond counts to be able to do everything in less than 33ms (aiming at 16ms). C# foreach statement is one of the worst performance killers, and here I explain why.
This Micro Tutorial demonstrates using Microsoft Excel pivot tables, how to reverse engineer competitors' marketing strategies through backlinks.
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…

776 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question