BAD_SEED
BAD_SEED

Reputation: 5056

Synchronize background worker

I have a code like this:

if (condition#1) {
   // step 2
   ConfigurazioneSA csa = new ConfigurazioneSA(...);
   WconfiguraSA.RunWorkerAsync(csa);
}
else
{
   // step 1
   PassaggioIE bo = new PassaggioIE(...);
   WpassIE.RunWorkerAsync(bo);

   if (condition#2) {
      // step 2
      ConfigurazioneSA csa = new ConfigurazioneSA(...);
      WconfiguraSA.RunWorkerAsync(csa);
   }
}

When execution flow is inside condition#1 branch, the step 1 block has been previously executed (in a previous execution of my application) so step 2 can be executed without any problem.

But, when execution flow is inside else branch I need to execute step 1 and when this step is completed I can execute step 2. Since I'm using BackgroundWorker as step 1 start, step 2starts immediately after causing error.

I would sinchronize this producer/consumer problem adding as less entropy as I can. All solutions that I found introduce a great amount of code, while I would a simply semaphore that avoid the step 2 execution until step 1 is not complete. Any ideas?

Upvotes: 0

Views: 3176

Answers (3)

unarist
unarist

Reputation: 616

If you don't want to use Tasks, you can use BackgroundWorker.RunWorkerCompleted event raised when its execution is completed.

// step 1
PassaggioIE bo = new PassaggioIE(...);

WpassIE.RunWorkerCompleted += (sender, e) => {

    // You might want to add error handling code here.

    if (condition#2) {
        // step 2
        ConfigurazioneSA csa = new ConfigurazioneSA(...);
        WconfiguraSA.RunWorkerAsync(csa);
    }
}

WpassIE.RunWorkerAsync(bo);

But I think using TPL is better too.

Upvotes: 0

unarist
unarist

Reputation: 616

IsBusy example:

else
{
   // step 1
   PassaggioIE bo = new PassaggioIE(...);
   WpassIE.RunWorkerAsync(bo);

   // wait for WpassIE to complete
   while(WpassIE.IsBusy) Application.DoEvents();

   if (condition#2) {
      // step 2
      ConfigurazioneSA csa = new ConfigurazioneSA(...);
      WconfiguraSA.RunWorkerAsync(csa);
   }
}

In this solution, you've to wait WpassIE completion.

and don't use Thread.Sleep instead of Application.DoEvents because it causes problem like BackgroundWorkers never stop being busy.

Upvotes: 0

Sriram Sakthivel
Sriram Sakthivel

Reputation: 73442

I'll suggest you to use Tpl for this. This can be achieved easily.

    Task.Factory.StartNew(() =>
    {
        //Step1
    }).ContinueWith(antecedent =>  //executed after step1 is done
    {
        if (condition#2) 
        {
        // step 2
        }
    });

Also note you'll not get events like Progress and Completed, you've to sacrifice. Completed event is similar to ContinuationTask.

One more difference here is ContinuationTask will execute in threadpool thread, If you want it in UI thread use TaskScheduler.FromCurrentSynchronizationContext

Upvotes: 1

Related Questions