当所有线程(backgroundWorkers)在.NET中完成其作业时,如何调用方法

时间:2010-05-03 08:12:21

标签: c# .net

我正在使用C#.NET。它是一个GUI应用程序。当用户单击按钮时,工作分配给4个不同的后台工作人员。每个花费不同的时间,最终结果是填充一些变量。

我需要调用一个方法来操作每个bgwoeker的这些最终结果并给出最终输出。如何做到这一点?

这里的问题是确保所有的工作人员完成了他们的工作。

3 个答案:

答案 0 :(得分:3)

您可以从每个BackgroundWorker的RunWorkerCompleted事件处理程序中创建计数器并检查它,或者从每个BackgroundWorker的RunWorkerCompleted检查其他3个Backgroundworker的状态。

答案 1 :(得分:1)

1)如果您实际上正在执行您希望完成的工作,请不要使用后台工作程序,使用正确的线程或如上所述,使用线程池。

2)参见手动重置事件示例[http://msdn.microsoft.com/en-us/library/system.threading.manualresetevent.aspx][1]

或者,使用.net 4并使用并行linq,简单!

IEnumerable<myDelegate> delegates;
delegates.AsParallel().ForEach(adelegate => adelegate());

完成!

编辑:如果我错过了你的后台线程的目的是停止GUI锁定,那么我可能只是启动一个新线程,一个接一个地执行任务,并只使用一个手动重置事件。当然,这实际上取决于您的要求。

答案 2 :(得分:0)

您可以将此功能封装在一个类中:

public class Synchronizer {
    private List<Action> workers = new List<Action>();
    public List<Action> Workers { get { return workers; } }

    public void Run( Action callBackOnDone ) {
        var workers Workers.ToArray();
        object syncRoot = new object();
        int counter = workers.Length;
        foreach( var worker in workers ) {
            ThreadPool.QueueUserWorkItem( ()=> {
                try { worker(); }
                finally {
                    lock(syncRoot) {
                         counter--;
                         if ( counter <= 0 ) {
                             callBackOnDone();
                         }
                    }
                }
            } );
        }
    }
}