多个背景工作者排队

时间:2012-06-21 20:08:17

标签: c# winforms asynchronous backgroundworker

在我的winforms应用程序中,我有一个包含对象的队列:

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

对于每个对象,我必须开始一个单独的背景工作者来做一些耗时的工作。

    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);
    }

我的问题是,在调用RunWorkerAsync之后,执行会跳转到while的下一次迭代(这是合乎逻辑的,因为worker正在运行异步,它允许下一次迭代发生)。

我真正需要做的是,告诉应用程序以某种方式等待,直到后台工作者完成工作,然后才开始下一次迭代,继续调用DoSingle()。

我应该对_queuedRows对象或类似的东西应用锁吗?谢谢,

2 个答案:

答案 0 :(得分:4)

不是在while循环中调用DoSingle,而是将其更改为调用DoSingle一次,然后在后台工作程序的RunWorkerCompleted事件处理程序中再次调用DoSingle,直到队列已经完成。

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

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

此外,由于您没有并行处理队列中的所有对象,因此只需将后台工作程序实例化一次并重复使用它。

答案 1 :(得分:0)

您必须只使用一名背景工作者。