Pause the new BackGroundWorker until the previous ones complete

I fight streams. The problem is that I am repeating the foreach loop.

When setting up, the this.Documentapplication performs a login, which starts with an event and takes a few seconds. In the method, worker_RunWorkerCompletedI need to perform some actions depending on the current login information.

The problem is that before I can perform this action for the first file, I this.Documentalready changed the application execution for another input. Thus, I can never carry out my actions.

My question is: how can I pause the next thread until the previous thread completes. Is there any other solution to my problem?

I tried with AutoResetEventbut I had no luck. I installed waitOne()right after calling RunWorkerAsync and .Set()in RunWorkerCompleted. The code never gets into RunWorkerCompleted...

Here is the code:

    public void Start(object obj)
    {
       try
       {
          foreach (KeyValuePair<string, Stream> pair in this.CollectionOfFiles)
          {
              Worker = new BackgroundWorker();
              Worker.DoWork += new DoWorkEventHandler(worker_DoWork);
              Worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);

          using (Stream stream = pair.Value)
              {
                primaryDocument = new Document(stream);

                DataHolderClass dataHolder = new DataHolderClass();
                dataHolder.FileName = pair.Key;
                dataHolder.Doc = secondaryDocument;

               //background thread call
                Worker.RunWorkerAsync(dataHolder);
              }
            }
          }

       catch (Exception ex)
       {
          // exception logic
}
       finally
       {
          // complete logic
       }
    }


    private void worker_DoWork(object sender, DoWorkEventArgs e)
    {
       DataHolderClass dataHolder = ((DataHolderClass)e.Argument);
       // setting this attribute triggers execution of login event
       this.Document = dataHolder.Doc;
       e.Result = (dataHolder);
    }


    private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
       // here I need to perform some actions that are depending on the current login
       DataHolderClass dataHolder = ((DataHolderClass)e.Result);
       this.eventAggregator.GetEvent<ActionEvent>().Publish(new Message(EMessageType.Info) { Title = dataHolder.FileName });
    }
+4
source share
3 answers

No9,

Try the following:

System.Threading.ManualResetEvent _busy = new System.Threading.ManualResetEvent(false);

void ResumeWorker() 
{
     // Start the worker if it isn't running
     if (!backgroundWorker1.IsBusy) backgroundWorker1.RunWorkerAsync(dataHolder);  
     // Unblock the worker 
     _busy.Set();
}

void PauseWorker() 
{
    // Block the worker
    _busy.Reset();
}

void CancelWorker() 
{
    if (backgroundWorker1.IsBusy) {
        // Set CancellationPending property to true
        backgroundWorker1.CancelAsync();
        // Unblock worker so it can see that
        _busy.Set();
    }
}

then in your code the method starts.

Let me know if this works :)

0
source
class SimpleWaitPulse
{
  static readonly object _locker = new object();
  static bool _go;

  static void Main()
  {                                // The new thread will block
    new Thread (Work).Start();     // because _go==false.

    Console.ReadLine();            // Wait for user to hit Enter

    lock (_locker)                 // Let now wake up the thread by
    {                              // setting _go=true and pulsing.
      _go = true;
      Monitor.Pulse (_locker);
    }
  }

  static void Work()
  {
    lock (_locker)
      while (!_go)
        Monitor.Wait (_locker);    // Lock is released while we’re waiting

    Console.WriteLine ("Woken!!!");
  }
}

Can you use momentum? Taken from: Threading in C # from albahari.com

0
source

, ... , . , :

public void Start(object obj)
{
    try
    {
        BackgroundWorker previousWorker = null;
        DataHolderClass previousWorkerParams = null;

        foreach (KeyValuePair<string, Stream> pair in this.CollectionOfFiles)
        {
            // signal event on previous worker RunWorkerCompleted event
            AutoResetEvent waitUntilCompleted = null;
            if (previousWorker != null)
            {
                waitUntilCompleted = new AutoResetEvent(false);
                previousWorker.RunWorkerCompleted += (o, e) => waitUntilCompleted.Set();

                // start the previous worker
                previousWorker.RunWorkerAsync(previousWorkerParams);
            }

            Worker = new BackgroundWorker();

            Worker.DoWork += (o, e) =>
            {
                // wait for the handle, if there is anything to wait for
                if (waitUntilCompleted != null)
                {
                    waitUntilCompleted.WaitOne();
                    waitUntilCompleted.Dispose();
                }
                worker_DoWork(o, e);
            };

            using (Stream stream = pair.Value)
            {
                primaryDocument = new Document(stream);

                DataHolderClass dataHolder = new DataHolderClass();
                dataHolder.FileName = pair.Key;
                dataHolder.Doc = secondaryDocument;

                // defer running this worker; we don't want it to finish
                // before adding additional completed handler
                previousWorkerParams = dataHolder;
            }

            previousWorker = Worker;
        }

        if (previousWorker != null)
        {
            previousWorker.RunWorkerAsync(previousWorkerParams);
        }
    }

    catch (Exception ex)
    {
        // exception logic
    }
    finally
    {
        // complete logic
    }
}
0

All Articles