繁体   English   中英

Fire and Forget 没有得到安排

[英]Fire and Forget not getting scheduled

我正在使用Task.Run(() => this.someMethod())来安排后台工作。 我对操作结果不感兴趣,需要继续申请流程。

但是,有时我的后台任务很长时间没有安排好。自从我们从 .Net 4.7 从 4.5 迁移以来,这种情况就开始发生了。 即使在调试时,断点要么没有被击中,要么在相当长的延迟(> 10 分钟)后被击中。

有没有人注意到这种行为或知道是什么原因造成的?

我在 i7 核心上运行,16 GB RAM。

让您的任务甚至需要 10 分钟才能开始听起来很可疑。 我的猜测是你的系统负载很重,或者你有很多任务在运行。

我将攻击后者(针对特定情况)。

任务创建选项

LongRunning指定任务将是一个长时间运行的粗粒度操作,涉及比细粒度系统更少、更大的组件。 它向 TaskScheduler 提供了一个提示,即可能需要超额订阅。 超额订阅使您可以创建比可用硬件线程数更多的线程。 它还向任务调度程序提供了一个提示,该任务可能需要一个额外的线程,以便它不会阻止其他线程或本地线程池队列上的工作项的前进进度。

var task = new Task(() => MyLongRunningMethod(),TaskCreationOptions.LongRunning);
task.Start();

这是Stephen Toub - MSFT在这篇文章中的引用

在幕后,这将导致使用更多线程,因为它的目的是允许 ThreadPool 继续处理工作项,即使一项任务运行了很长时间; 如果该任务在池中的线​​程中运行,则该线程将无法为其他任务提供服务。 如果您通过性能测试发现不使用 LongRunning 会导致其他工作的处理长时间延迟,则通常只使用 LongRunning。

如果不查看所有代码,很难知道您的问题是什么,但是我将此作为建议发布。

我不知道您以这种方式启动了多少任务,但除非数量真的很高,否则我会将调试重点放在被调用的方法上,而不是调用者上。 10 分钟的延迟更可能是由死锁或网络问题而不是任务调度引起的。

一些想法:

  1. 首先,我会在被调用方法的开头和结尾添加一些内容,让您知道它何时开始执行以及何时完成。 就像带有时间戳和任务 ID 的 Debug.WriteLine()。
  2. 确保被调用的方法释放所有资源,即使它崩溃了。 崩溃的线程/任务可能不会被注意到,因为它们不会导致应用程序崩溃。
  3. 仔细检查被调用的方法是否是线程安全的。 过去您可能很幸运,而一些新的框架优化现在正在造成严重破坏。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM