C# 多后台工作队列

C# 多后台工作队列,c#,winforms,asynchronous,backgroundworker,C#,Winforms,Asynchronous,Backgroundworker,在我的winforms应用程序中,我有一个包含以下对象的队列: Queue<MyObj> _queuedRows = new Queue<MyObj>(); Queue\u queuedRows=new Queue(); 对于每个对象,我必须启动一个单独的backgroundworker来完成一些耗时的工作 private void DoAll(List<MyObj> lst) { foreach (MyObj o

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

    Queue<MyObj> _queuedRows = new Queue<MyObj>();
Queue\u queuedRows=new Queue();
对于每个对象,我必须启动一个单独的backgroundworker来完成一些耗时的工作

    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);
    }
private void DoAll(列表lst)
{
foreach(第一层中的MyObj o)
{
_排队(o);
}
while(_queuedRows.Any())
DoSingle();
}
私有void DoSingle()
{
如果(!isCancelPending())
{
if(_queuedRows.Any())
{
MyObj currentObj=_queuedRows.Dequeue();
InitBackgroundWorker(currentObj);
}
}
}
私人后台工作人员(MyObj currentObj)
{
BackgroundWorker_worker=新的BackgroundWorker();
_worker.worker支持扫描单元=true;
_worker.WorkerReportsProgress=true;
_worker.DoWork+=新的doworkereventhandler(worker\u DoWork);
_worker.RunWorkerCompleted+=新的RunWorkerCompletedEventHandler(worker\u RunWorkerCompleted);
如果(!\u worker.IsBusy&¤tObj!=null)
_worker.RunWorkerAsync(currentObj);
}
我的问题是,在调用RunWorkerAsync之后,执行跳转到while的下一个迭代(这是合乎逻辑的,因为worker正在异步运行,它允许下一个迭代发生)

实际上,我需要做的是告诉应用程序以某种方式等待backgroundworker完成工作,然后才应该通过继续调用DoSingle()开始下一次迭代


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

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

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

        if (_queuedRows.Any())
            DoSingle();
    }
private void DoAll(列表lst)
{
foreach(第一层中的MyObj o)
{
_排队(o);
}
if(_queuedRows.Any())
DoSingle();
}

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

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

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

        if (_queuedRows.Any())
            DoSingle();
    }
private void DoAll(列表lst)
{
foreach(第一层中的MyObj o)
{
_排队(o);
}
if(_queuedRows.Any())
DoSingle();
}

另外,由于您没有并行处理队列中的所有对象,请仅实例化一次后台工作程序并重用它。

您必须只使用一个backgroundworker。

您必须只使用一个backgroundworker。

您必须使用后台工作程序吗?使用任务将是一个非常好的解决方案。谢谢你的链接,它非常有用,我不知道。BackgroundWorker不是强制性的,我认为这是一种在应用程序运行时防止阻塞UI的方法。是的,BackgroundWorker适用于快速简单的应用程序,以防止UI阻塞。对于更高级的内容,请使用任务。NET4中的TPL太棒了!你必须使用后台工作人员吗?使用任务将是一个非常好的解决方案。谢谢你的链接,它非常有用,我不知道。BackgroundWorker不是强制性的,我认为这是一种在应用程序运行时防止阻塞UI的方法。是的,BackgroundWorker适用于快速简单的应用程序,以防止UI阻塞。对于更高级的内容,请使用任务。NET4中的TPL太棒了!