等待多个背景线程

时间:2012-10-04 14:27:46

标签: c# multithreading c#-4.0 thread-safety monitoring

我想知道所有线程何时在多线程程序中完成

没有像汇集一样的东西

while(!allThreadFinished){
thread.sleep(100);
}

解决方案应该使用Monitor但我不能如何批准它是正确的。 由于以下代码中的“SomeMethod”使用网络,因此消耗时间。

public object SomeMethod(string input);
public object[] MultiThreadMethod(string[] inputs) {
            var result = new object[inputs.Count()];
            int i = 0;
            foreach (var item in inputs) {
                BackgroundWorker work = new BackgroundWorker();
                work.DoWork += (sender, doWorkEventArgs) => { doWorkEventArgs.Result = SomeMethod(item); };
                work.RunWorkerCompleted += (sender, runWorkerCompletedEventArgs) => { 
                    result[i] = runWorkerCompletedEventArgs.Result; 
                };
                i++;
                work.RunWorkerAsync();
            }
            /////////////////////////////////////////////////////////////
            //**wait while all thread has been completed**
            /////////////////////////////////////////////////////////////
            return result;
        }

4 个答案:

答案 0 :(得分:3)

尝试使用TPL http://msdn.microsoft.com/en-us/library/dd460717.aspx

 List<Task> tasks = new List<Task>();

 Task t1 = new Task(() =>
 {
    // Do something here...

 });
 t1.Start();
 tasks.Add(t1);

 Task t2 = new Task(() =>
 {
    // Do something here...

 });
 t2.Start();
 tasks.Add(t2);

 Task.WaitAll(tasks.ToArray());

答案 1 :(得分:2)

你可以使用TPL来做同样的事情,你将避免使用Thread.Sleep(),它会更清晰。看看这个:http://msdn.microsoft.com/en-us/library/dd537610.aspx

您使用TPL的示例如下所示(未经测试的代码):

    private ConcurrentBag<object> _results;
    public object[] MultiThreadMethod(string[] inputs)
    {
        _results = new ConcurrentBag<object>();
        var tasks = new Task[inputs.Length];
        for (int i = 0; i < inputs.Length; i++)
        {
            tasks[i] = Task.Factory.StartNew(() => DoWork(inputs[i]));
        }

        Task.WaitAll(tasks);
        return _results.ToArray();
    }

    private void DoWork(string item)
    {
        _results.Add(SomeMethod(item));
    }

编辑:没有ConcurrentBag:

public object[] MultiThreadMethod(string[] inputs)
    {
        var tasks = new Task<object>[inputs.Length];
        for (int i = 0; i < inputs.Length; i++)
        {
            tasks[i] = Task<object>.Factory.StartNew(() => DoWork(inputs[i]));
        }

        Task.WaitAll(tasks);
        return tasks.Select(task => task.Result).ToArray();
    }

    private object DoWork(string item)
    {
        return SomeMethod(item);
    }

答案 2 :(得分:1)

RunWorkerCompleted事件挂钩BackgroundWorker。工作完成后会触发。

可以找到如何正确使用BackgroundWorker的完整示例here

答案 3 :(得分:0)

http://msdn.microsoft.com/en-us/library/dd537608.aspx

//顺序版

foreach (var item in sourceCollection)
    Process(item);

//并行等价

Parallel.ForEach(sourceCollection, item => Process(item));