在foreach循环中创建任务

时间:2014-08-05 19:05:36

标签: c#

我有一个典型的foreach循环,它调用一个方法,其中参数是我们循环的集合的一个元素;像这样的东西:

foreach (byte x in SomeCollection)
{
   SomeMethod(x);
}

问题是SomeMethod需要很长时间才能运行。我想将调用移动到一个新任务,以便循环只创建任务,然后调用循环的线程继续。我如何以线程安全的方式执行此操作?

感谢。

修改 我遇到了性能问题,因为SomeMethod进行了几次数据库调用。所以我将循环转换为Parallel.ForEach,但这并没有太大的区别,因为每个线程然后调用数据库。我要做的只是创建在后台运行的任务,让主线程继续。

3 个答案:

答案 0 :(得分:11)

一种方法是使用Parallel.ForEach来执行此操作:

Parallel.ForEach(SomeCollection, x => SomeMethod(x));

代码将在继续之前等待SomeMethod的所有调用完成,但各个调用可以并行运行。

如果您不想等待通话结束,请将此通话包裹在StartNew中:

Task.Factory.StartNew(() => Parallel.ForEach(SomeCollection, x => SomeMethod(x)));

答案 1 :(得分:1)

您期望什么线程安全?这将是线程安全的:

foreach (byte x in SomeCollection) { Task.Factory.StartNew(() => SomeMethod(x)); }

直到你的方法不修改任何共享状态,这本身并不是线程安全的。

答案 2 :(得分:1)

你可以这样:

IEnumerable<Task> doWork()
{
  foreach(var x in SomeCollection)
    yield return Task.Run(()=>SomeMethod(x);
}

Task.WhenAll(doWork());

这将同时运行它们。