2

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

没有像池这样的东西

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

该解决方案应该使用监视器,但我无法批准它是正确的。由于以下代码中的“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

4 回答 4

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());
于 2012-10-04T14:32:07.513 回答
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);
    }
于 2012-10-04T14:40:56.520 回答
1

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

可以在这里找到如何正确使用 BackgroundWorker 的完整示例。

于 2012-10-04T14:31:02.883 回答
0

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

// 顺序版本

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

// 并行等价

Parallel.ForEach(sourceCollection, item => Process(item));
于 2012-10-04T19:03:32.687 回答