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

发布于 2024-09-18 06:07:34 字数 794 浏览 4 评论 0原文

我有一个正在执行的基本任务队列(与 3 个独立系统通信的 c# WinForms 应用程序)。一切都很好,直到其中一个 Web 服务决定不以通常的速度响应。

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

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

基于评论/答案的添加

任务可以同时运行。为了速度的目的,我选择不仔细研究多线程设计,但我现在正在考虑在面对不频繁的任务延迟时获得一致的性能。

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

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

我想我正在寻找类似于线程池的东西,但它只在检测到延迟时启动额外的线程。

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

我没有使用 BackgroundWorker 组件的原因是因为它们似乎是为您知道需要多少个工作人员的情况而构建的,并且我最好保持设计灵活

PS:再次感谢。 谢谢!

I have a basic queue of tasks executing (c# WinForms App that talks to 3 separate systems). Everything is great until one of the web services decides not to respond in with the usual speed.

I'm not interested in speeding things up via multi threading the jobs, but now that I am using it in production, I can see the benefit of having at least two threads running jobs - if one blocks and it's an anomaly, the other will keep truckin', and if both block, then probably any number of threads would and I just deal with it.

So, the question is: is this a common pattern I just described, and is there a name for that pattern and/or some awesome reference or framework, or anything to help me not re-invent any wheels.

Additions based on Comments/Answers

The tasks can be run simultaneously. I have chosen not to peruse a multi-threaded design for the purposes of speed, but I am now considering it to attain consistent performance in the face of infrequent task latency.

My assumption is that every once in a while a call to a web service takes disproportionately longer to complete while still being considered non-exceptional. This has a NON(corrected)-negligible impact on the total run time of, say, N jobs, if the average execution time is 1 second (including a host of disparate web service calls) and 0.0001% of the time a web service takes 15 seconds to respond.

Is a thread pool just another way of saying, "spin up worker threads and manage their state manually" ? Or is there something that can help me manage the complexity? I worry that the chance of introducing bug(s) grows out of proportion to the benefits in this case...

I think I am looking for something similar to a thread pool, but one that only spins up additional threads when latency is detected.

If anyone can give me more info on what one of the comments refers to as a work-stealing thread, that sounds promising.

The reason I didn't use the BackgroundWorker component is because they seem to be built for the case when you know how many workers you want, and I'd ideally keep the design flexible

PS: Thanks again.
Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

忆依然 2024-09-25 06:07:34

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

It depends on how important is the order of the queue items and how important it is that an item is completed before the next one is processed.
If one item must be completely processed before the next one is, then basically you are stuck.
If not, you may decide to implement a simple pool of worker threads. if .NET 4.0 is an option I would recommend using the Parallel Extensions for that and especially the AsParallel() and AsOrdered() methods.

淡淡の花香 2024-09-25 06:07:34

听起来您可能在这里寻找的是后台工作者。一个巧妙地封装启动工作线程、监视进度和接收结果的类。 http://msdn.microsoft.com/en-us/库/system.componentmodel.backgroundworker.aspx。使用起来既快捷又简单,只需连接 DoWork、ProgressChanged 和 RunWorkerCompleted 事件,然后启动它即可。

It sounds like what you might be looking for here is the Backgroundworker. A class that neatly encapsulates launching a worker thread, monitoring progress and receiving results. http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx. It's quick and easy to use just wire up the DoWork, ProgressChanged and RunWorkerCompleted events and then start it.

赏烟花じ飞满天 2024-09-25 06:07:34

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

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

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

The producer-consumer pattern may be the best fit for this, and using a queue (either Queue<T> wrapped in a lock or the new ConcurrentQueue<T>) is a good approach. It also gives you a place to recycle web service requests that fail due to timeouts or dropped connections.

If you want to use more than the maximum default of two simultaneous web connections then add this to your app.config (replace "10" with your new maximum):

<configuration>
  <system.net>
    <connectionManagement>
      <add address="*" maxconnection="10"/>
    </connectionManagement>
  </system.net>
</configuration>
月光色 2024-09-25 06:07:34

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

If you're using .Net 4 you can also have a look at Tasks

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文