我有一个符合
的功能 private void DoSomethingToFeed(IFeed feed)
{
feed.SendData(); // Send data to remote server
Thread.Sleep(1000 * 60 * 5); // Sleep 5 minutes
feed.GetResults(); // Get data from remote server after it's processed it
}
我想要并行化这个,因为我有很多相互独立的供稿。基于this answer,将Thread.Sleep()
留在那里并不是一个好主意。我还想等待所有线程都旋转起来,直到他们都有机会获得他们的结果。
处理这样的场景的最佳方法是什么?
编辑,因为我不小心将其删除了:我最初考虑将此函数称为Parallel.ForEach(feeds, DoSomethingToFeed)
,但我想知道当我找到时,是否有更好的方法来处理睡眠问题我联系的答案。
答案 0 :(得分:3)
我认为你应该看一下.NET中的Task
类。除了更低级别的线程/线程池管理之外,它是一个很好的抽象。
为了等待所有任务完成,您可以使用Task.WaitAll
。
Task
的使用示例如下:
IFeed feedOne = new SomeFeed();
IFeed feedTwo = new SomeFeed();
var t1 = Task.Factory.StartNew(() => { feedOne.SendData(); });
var t2 = Task.Factory.StartNew(() => { feedTwo.SendData(); });
// Waits for all provided tasks to finish execution
Task.WaitAll(t1, t2);
但是,另一种解决方案是使用Parallel.ForEach
为您处理所有Task
创建,并执行相应的任务批处理。对这两种方法进行了很好的比较here - 除了其他优点之外,还说明了:
Parallel.ForEach在内部使用分区程序将您的集合分发到工作项中。它不会对每个项目执行一项任务,而是批量处理以降低所涉及的开销。
答案 1 :(得分:3)
除非你有很多线程,否则你可以保持简单。创建所有线程。你会得到一些线程创建开销,但由于线程基本上一直在休眠,你不会得到太多的上下文切换。
编码比任何其他解决方案更容易(除非您使用的是C#5)。所以从这开始,只有在你真正看到性能问题时才能改进它。
答案 2 :(得分:1)
检查WaitHandle等待任务。
答案 3 :(得分:0)
private void DoSomethingToFeed(IFeed feed)
{
Task.Factory.StartNew(() => feed.SendData())
.ContinueWith(_ => Delay(1000 * 60 * 5)
.ContinueWith(__ => feed.GetResults())
);
}
//http://stevenhollidge.blogspot.com/2012/06/async-taskdelay.html
Task Delay(int milliseconds)
{
var tcs = new TaskCompletionSource<object>();
new System.Threading.Timer(_ => tcs.SetResult(null)).Change(milliseconds, -1);
return tcs.Task;
}