C# 开火,忘记没有预定的时间

C# 开火,忘记没有预定的时间,c#,.net,multithreading,task,task-parallel-library,C#,.net,Multithreading,Task,Task Parallel Library,我正在使用Task.Run(()=>this.someMethod())来安排后台作业。我对操作结果不感兴趣,需要继续应用流程 但是,有时我的后台任务很长一段时间都没有安排。自从我们从.NET4.7从4.5迁移到.NET4.7之后,这种情况就开始发生了。即使在调试时,断点也未命中或在相当长的延迟(>10分钟)后命中 有没有人注意到这种行为或者知道是什么导致的 我使用的是i7内核、16 GB内存。让您的任务花10分钟甚至启动听起来有些可疑。我猜你的系统负载很重,或者你有很多任务在运行 我将稍后攻击

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

但是,有时我的后台任务很长一段时间都没有安排。自从我们从.NET4.7从4.5迁移到.NET4.7之后,这种情况就开始发生了。即使在调试时,断点也未命中或在相当长的延迟(>10分钟)后命中

有没有人注意到这种行为或者知道是什么导致的


我使用的是i7内核、16 GB内存。

让您的任务花10分钟甚至启动听起来有些可疑。我猜你的系统负载很重,或者你有很多任务在运行

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

长时间运行指定任务将是长时间运行的, 粗粒度操作,涉及的组件比 细粒度系统。它向TaskScheduler提供以下提示: 超额认购可能是有保证的。超额订阅允许您创建 线程数超过可用的硬件线程数。它也 向任务计划程序提供一个提示,提示可能会有其他线程 任务需要,以便它不会阻止转发 本地线程池上其他线程或工作项的进度 排队

这是一段关于这个的引用

在封面下,它将导致更多的线程 正在使用,因为其目的是允许线程池继续 即使一个任务正在为扩展任务运行,也要处理工作项 一段时间;如果该任务正在池中的线程中运行, 该线程将无法服务于其他任务。你通常会 只有在通过性能测试发现 使用它会导致其他工作的长时间延迟


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

我不知道有多少任务是以这种方式启动的,但除非数量非常高,否则我会将调试重点放在被调用的方法上,而不是调用方。与任务调度相比,死锁或网络问题更有可能导致10分钟的延迟

一些想法:

  • 首先,我会在调用的方法的开头和结尾添加一些东西,让您知道它何时开始执行,何时结束。类似于带有时间戳和任务ID的Debug.WriteLine()
  • 确保被调用的方法释放所有资源,即使它崩溃。崩溃的线程/任务可能会被忽略,因为它们不会导致应用程序崩溃
  • 仔细检查所调用的方法是否是线程安全的。您可能在过去很幸运,一些新的框架优化现在正在造成严重破坏

  • 您是否有很多其他任务在后台运行?这里还有一些输入:-系统没有任何负载。这种“失火即忘”的操作有时有效,但并非一直有效。任务中的工作不是长时间运行的。它将通过网络连接并发送一些数据,数据小于1MB,并在几毫秒内传输。但重要的是,这段时间不能干扰主流。不,系统没有任何负载。即使在调试时,我也看不到任务被调度,我只触发了一个操作。该操作必须调用fire和forget操作。代码是非常简单的public void操作(){Do some stuff Task.Run(()=>this.somemethod())return;}public void somemethod(){}再说一次,正在运行的任务并不多。问题是任务还没有开始,我已经设置了一个断点,以确保在任务开始时我能抓住它,但它从来没有击中它。我在少数地方使用火和遗忘,但似乎在每个地方都是一个常见的问题。也没有资源问题。没有线程级别的争用。我还尝试了显式线程,比如新线程(()=>{}).Start()。再说一次,运气不好。尝试将代码更改为最简单的列表添加方法任务。运行(()=>List.add()。未执行:(听起来很奇怪,根据Microsoft更改日志,从4.5到4.7,线程或任务没有发生任何更改。您确定转换工作正常,并且没有破坏您的环境吗?如果等待任务,会发生什么情况?几秒钟后,任务的状态如何?
    var task = new Task(() => MyLongRunningMethod(),TaskCreationOptions.LongRunning);
    task.Start();