2

我有一个功能是

   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
   }

我想将此并行化,因为我有很多相互独立的提要。基于这个答案,把它留Thread.Sleep()在里面并不是一个好主意。我还想在所有线程都启动后等待,直到它们都有机会获得结果。

处理这种情况的最佳方法是什么?

编辑,因为我不小心遗漏了它:我最初考虑将此函数称为Parallel.ForEach(feeds, DoSomethingToFeed),但是当我找到链接到的答案时,我想知道是否有更好的方法来处理睡眠。

4

4 回答 4

3

我认为你应该看看Task.NET 中的类。它是更底层线程/线程池管理之上的一个很好的抽象。

为了等待所有任务完成,您可以使用Task.WaitAll.

使用 s 的示例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创建并执行适当的任务批处理。这里给出了这两种方法的一个很好的比较- 其中,除其他优点外,它指出:

Parallel.ForEach 在内部使用 Partitioner 将您的集合分配到工作项中。它不会对每个项目执行一项任务,而是将其批处理以降低所涉及的开销。

于 2012-10-24T22:04:12.353 回答
3

除非你有很多线程,否则你可以保持简单。创建所有线程。您将获得一些线程创建开销,但由于线程基本上一直处于休眠状态,因此您不会获得太多的上下文切换。

它比任何其他解决方案都更容易编码(除非您使用的是 C# 5)。所以从那开始,只有当你真正看到性能问题时才改进它。

于 2012-10-24T22:22:04.837 回答
1

检查WaitHandle等待任务。

于 2012-10-24T22:04:28.210 回答
-1
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;
}
于 2012-10-24T22:35:05.677 回答