提问人:sbi 提问时间:10/15/2009 最后编辑:sbi 更新时间:10/15/2009 访问量:1914
如何在 C 语言中使这个循环的主体并行运行#
How to make this loop's body run in parallel in C#
问:
我有一个这样的循环
ICollection<Data> GetData()
{
ICollection<Data> result = new List<Data>()
foreach (var item in aCollection)
item.AddData(result);
return result;
}
我现在需要并行执行,而是迭代执行。我的第一次尝试是做这样的催眠
ICollection<Data> GetData()
{
ICollection<Data> result = new SynchronizedCollection<Data>()
foreach (var item in aCollection)
new Thread(delegate() { item.AddData(result); }).Start();
return result;
}
但是我需要一种方法来等待所有数据添加完毕,然后再返回结果。
最简单的方法是什么?
编辑:这将通过网络进行呼叫。在集合中通常最多有几十个条目。AddData
答:
在 C#4.0 中,可以使用如下内容:
Parallel.ForEach<Data>(aCollection, delegate(Data d)
{
d.AddData(result);
});
评论
存储对创建的线程对象的引用,并对每个对象调用 join:
ICollection<Data> GetData()
{
ICollection<Data> result = new SynchronizedCollection<Data>()
List<Thread> threads=new List<Thread>();
foreach (var item in aCollection)
{
Thread thread=new Thread(delegate() { item.AddData(result); });
thread.Start();
threads.Add(thread);
}
foreach(Thread thread in threads)
thread.Join();
return result;
}
评论
除非 AddData 非常非常慢,否则创建新线程的开销很可能是代码中的瓶颈。
如果您确实想将其移交给其他线程,则应使用 ThreadPool。至于等待线程完成,您可以使用等待句柄在线程之间发出信号。
评论
AddData
最简单的方法可能是等待 parallels 框架在 4.0 中出现。
好吧,对于初学者来说,您需要小心在那里创建线程。如果您有数百甚至数千个项目,则该代码可能会扼杀您的应用,或者至少会降低您的性能。
我将尝试将 AddData 方法设计为异步调用。IAsyncResult 具有 WaitHandle。您可以等待这些句柄,直到所有 asyncresults 都表明操作已完成。然后你就可以继续了。异步执行此操作应确保使用线程池中的线程。这样一来,你就可以获得相当不错的性能,如果你的列表变得非常大,你就会达到工作线程的自然饱和度。
评论
您可以使用并行扩展,它将集成在 C# 4.0 中,并作为单独的库用于 C# 3.5,您可以在此处下载:Microsoft Parallel Extensions to .NET Framework 3.5。
如果不想使用并行扩展,请不要为每次迭代启动一个线程,而是改用 ThreadPool,这样可以提高性能。
正如我在这个答案的评论中了解到的那样,List<> 不是线程安全的,为什么你应该使用 SynchronizedCollection<> 代替。
下面是使用线程池的代码示例。
IEnumerable<object> providers = null;
var waitHandles = new List<WaitHandle>();
foreach (var provider in providers)
{
var resetEvent = new ManualResetEvent(false);
waitHandles.Add(resetEvent);
ThreadPool.QueueUserWorkItem(s =>
{
// do whatever you want.
((EventWaitHandle)s).Set();
}, resetEvent);
}
WaitHandle.WaitAll(waitHandles.ToArray());
评论
SynchronizedCollection
List<T>
SynchronizedCollection<T>
评论