2

in my winforms app, I have a Queue which contains objects:

    Queue<MyObj> _queuedRows = new Queue<MyObj>();

For each object, I must start a separate backgroundworker to do some timeconsuming job.

    private void DoAll(List<MyObj> lst)
    {
        foreach (MyObj o in lst)
        {
            _queuedRows.Enqueue(o);
        }

        while (_queuedRows.Any())
            DoSingle();
    }

    private void DoSingle()
    {
        if (!isCancelPending())
        {
            if (_queuedRows.Any())
            {
                MyObj currentObj = _queuedRows.Dequeue();
                InitBackgroundWorker(currentObj);
            }
        }
    }

    private void InitBackgroundWorker(MyObj currentObj)
    {
        BackgroundWorker _worker = new BackgroundWorker();
        _worker.WorkerSupportsCancellation = true;
        _worker.WorkerReportsProgress = true;
        _worker.DoWork += new DoWorkEventHandler(worker_DoWork);
        _worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);

        if (!_worker.IsBusy && currentObj != null)
            _worker.RunWorkerAsync(currentObj);
    }

My problem is, after the call to RunWorkerAsync, the execution jumps to the next iteration of the while (which is logical, as the worker is running async and it allows for the next iteration to happen).

What I actually need to do, is to tell the app somehow to WAIT until the backgroundworker has completed the job, and only then should it start the next iteration by continuing with calling DoSingle().

Should I apply a lock on the _queuedRows object or something similar? Thanks,

3
  • 3
    Do you have to use a background worker? Using Tasks would be a very nice solution to this. msdn.microsoft.com/en-us/library/dd235608 Commented Jun 21, 2012 at 20:10
  • Thank you for the link, its very useful, didnt know about that. The BackgroundWorker is not mandatory, it was something I thought of as a way to prevent blocking the UI while the app works. Commented Jun 21, 2012 at 20:12
  • Yeah, BackgroundWorker is good for fast and simple applications to prevent UI from blocking. For anything more advanced, use tasks. TPL in .net 4 is awesome! Commented Jun 22, 2012 at 14:37

2 Answers 2

4

Instead of calling DoSingle in the while loop, change it to call DoSingle once and then in the background worker's RunWorkerCompleted event handler call DoSingle again and again until the queue is done.

    private void DoAll(List<MyObj> lst)
    {
        foreach (MyObj o in lst)
        {
            _queuedRows.Enqueue(o);
        }

        if (_queuedRows.Any())
            DoSingle();
    }

Also since you're not processing all objects in the queue in parallel, instantiate background worker only once and reuse it.

Sign up to request clarification or add additional context in comments.

Comments

0

You must use only one backgroundworker.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.