w12*_*128 5 .net c# task threadpool task-parallel-library
在处理任务时,经验法则似乎是线程池 - 通常由例如调用Task.Run()或Parallel.Invoke() - 使用 - 应该用于相对较短的操作.当处理长时间运行的操作时,我们应该使用该TaskCreationOptions.LongRunning标志 - 据我所知 - 避免堵塞线程池队列,即将工作推送到新创建的线程.
但究竟什么是长期运行?从时间上看,多长时间?在决定是否使用时,除了预期任务持续时间之外还有其他因素LongRunning,例如预期的CPU架构(频率,核心数量......)或将尝试运行的任务数量从程序员的角度来看?
例如,假设我有500个任务要在专用应用程序中处理,每个任务需要10-20秒才能完成.我应该只使用Task.Run启动所有500个任务(例如在循环中),然后等待它们全部,也许是LongRunning,同时保留默认的最大并发级别?然后,如果我设置LongRunning在这种情况下,这将不会创建500个新线程,并且实际上会导致大量开销和更高的内存使用(由于额外的线程被分配)与省略相比LongRunning?这假设在等待这500个任务时不会安排执行新任务.
我猜测设置的决定LongRunning取决于在给定时间间隔内对线程池发出的请求数量,而这LongRunning应该仅用于预期比大多数线程池放置的任务花费更长时间的任务 - 根据定义,最多只占所有任务的一小部分.换句话说,这似乎是一个排队和线程池利用率优化问题,应该通过测试逐个解决,如果有的话.我对么?
这有点无关紧要.问题不在于时间,而在于你的代码在做什么.如果您正在进行异步I/O,那么您仅在单个请求之间的短时间内使用该线程.如果你在做CPU工作......好吧,你正在使用CPU.没有"线程池饥饿",因为CPU被充分利用.
真正的问题是当你正在进行不使用CPU的阻塞工作时.在这种情况下,线程池饥饿导致CPU利用不足 - 你说"我需要CPU来完成我的工作"然后你实际上并没有使用它.
如果你不使用阻塞的API,有一个在不使用点Task.Run使用LongRunning.如果必须异步运行一些传统的阻塞代码,使用LongRunning可能是一个好主意.总工作时间不如"你经常这样做"的重要性.如果根据用户点击GUI启动一个线程,与首先单击按钮的行为中已包含的所有延迟相比,成本很小,并且您可以正常使用LongRunning以避免线程池.如果你正在运行一个产生大量阻塞任务的循环......那就停止这样做了.这是一个坏主意:D
例如,假设没有异步API替代方案File.Exists.因此,如果您发现这给您带来了麻烦(例如,通过错误的网络连接),您可以使用它来启动它Task.Run- 并且因为您没有进行CPU工作,所以您可以使用LongRunning.
相比之下,如果你需要做一些基本上100%CPU工作的图像处理,那么操作需要多长时间并不重要 - 这不是一LongRunning件事.
最后,最常见的使用方法LongRunning是当你的"工作"实际上是老派"循环并定期检查是否应该完成某些事情,然后再进行循环".长时间运行,但99%的时间只是阻止一些等待句柄或类似的东西.同样,这仅在处理不受CPU限制但没有适当异步API的代码时才有用.例如,如果你需要编写自己的东西,你可能会发现类似的东西SynchronizationContext.
现在,我们如何将此应用于您的示例?好吧,我们不能,不是没有更多的信息.如果您的代码是CPU限制的,Parallel.For并且朋友就是您想要的 - 那些确保您只使用足够的线程来保证CPU,并且可以使用线程池.如果它不受 CPU限制...除了使用之外你还没有任何选择,LongRunning如果你想并行运行任务.理想情况下,此类工作将包含您可以安全地调用的异步调用以及await Task.WhenAll(...)您自己的线程.
在处理任务时,一个经验法则似乎是线程池——通常用于调用 Task.Run() 或 Parallel.Invoke()——应该用于相对较短的操作。当处理长时间运行的操作时,我们应该将 TaskCreationOptions.LongRunning 设置为 true 以 - 据我所知 - 避免阻塞线程池队列,即将工作推送到新创建的线程。
绝大多数时候,你根本不需要使用LongRunning,因为线程池会在 2 秒后调整到“丢失”一个线程到长时间运行的操作。
主要问题LongRunning是它迫使您使用非常危险的StartNewAPI。
换句话说,这似乎是一个排队和线程池利用率优化问题,如果有的话,应该通过测试逐案解决。我对么?
是的。LongRunning第一次编写代码时永远不应该设置。如果您看到由于线程池注入率导致的延迟,那么您可以仔细添加LongRunning.
| 归档时间: |
|
| 查看次数: |
3338 次 |
| 最近记录: |