是否有一种标准模式可以避免由于单个被阻止的任务而导致作业队列中的延迟?

时间:2010-09-07 15:14:44

标签: c# design-patterns task-queue

我有一个基本的任务队列(c#WinForms App与3个不同的系统对话)。一切都很好,直到其中一个Web服务决定不以通常的速度响应。

我对通过多线程处理作业来加快速度感兴趣,但是现在我在生产中使用它,我可以看到至少有两个线程运行作业的好处 - 如果一个块阻塞并且它是异常的,另一个将保持卡车',如果两个都阻止,那么可能任意数量的线程,我只是处理它。

所以,问题是:这是我刚才描述的常见模式,是否有该模式的名称和/或一些非常棒的参考或框架,或任何可以帮助我不重新发明轮子的东西。

基于评论/答案的补充

任务可以同时运行。我已经选择不考虑速度的多线程设计,但我现在正考虑在面对不常见的任务延迟时获得一致的性能。

我的假设是,每隔一段时间,对Web服务的调用就会花费不成比例的时间来完成,同时仍然被认为是非特殊的。如果平均执行时间为1秒(包括大量不同的Web服务调用),则对N个作业的总运行时间有一个NON(更正)不可忽略的影响,并且Web服务占用的时间为0.0001% 15秒响应。

线程池只是另一种说法,“启动工作线程并手动管理其状态”?或者有什么东西可以帮助我管理复杂性?我担心引入bug的可能性与这种情况下的好处不成比例......

我认为我正在寻找类似于线程池的东西,但是只有在检测到延迟时才会旋转其他线程。

如果有人能够提供更多关于其中一条评论所指的工作窃取线程的信息,那听起来很有希望。

我没有使用BackgroundWorker组件的原因是因为它们似乎是在你知道你想要多少工人的情况下构建的,我理想的是保持设计的灵活性

PS:再次感谢。 谢谢!

4 个答案:

答案 0 :(得分:3)

这取决于队列项的顺序有多重要,以及在处理下一个项之前完成项的重要性。 如果一个项目必须在下一个项目之前完全处理,那么基本上你就会陷入困境。 如果没有,您可以决定实现一个简单的工作线程池。如果.NET 4.0是一个选项,我建议使用Parallel Extensions,尤其是AsParallel()和AsOrdered()方法。

答案 1 :(得分:1)

听起来你可能正在寻找的是背景工作者。一个整齐地封装启动工作线程,监视进度和接收结果的类。 http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx。只需简单地连接DoWork,ProgressChanged和RunWorkerCompleted事件,然后启动它即可快速轻松地使用。

答案 2 :(得分:1)

生产者 - 消费者模式可能最适合这种情况,使用队列(Queue<T>包裹在lock或新ConcurrentQueue<T>)是一种很好的方法。它还为您提供了回收由于超时或断开连接而失败的Web服务请求的位置。

如果您想使用超过两个同时网络连接的最大默认值,请将其添加到您的app.config中(用新的最大值替换“10”):

<configuration>
  <system.net>
    <connectionManagement>
      <add address="*" maxconnection="10"/>
    </connectionManagement>
  </system.net>
</configuration>

答案 3 :(得分:0)

如果您正在使用.Net 4,您还可以查看任务