C# 在任务上指定长时间运行有多重要?

C# 在任务上指定长时间运行有多重要?,c#,task-parallel-library,C#,Task Parallel Library,强调将任务创建标志放入较新的API可能有点混乱,特别是使用async模式 我发现这篇文章声称它对async不是一个好主意,不应该使用: 我的理解是,实际上,这个标志将导致TPL启动一个专用线程,而不是强调线程池,但特别是如果我的应用程序不涉及大量并行任务,这真的有什么大不了的吗?如果预期的并行度小于默认的线程池大小(无论是什么),我可以安全地忽略该标志吗?最糟糕的情况是,线程池可能会在几百毫秒内缺少线程?线程池背后的整个想法是创建任务需要几毫秒,因为它要求操作系统创建它,切换上下文等等。。。所以

强调将任务创建标志放入较新的API可能有点混乱,特别是使用
async
模式

我发现这篇文章声称它对
async
不是一个好主意,不应该使用:


我的理解是,实际上,这个标志将导致TPL启动一个专用线程,而不是强调线程池,但特别是如果我的应用程序不涉及大量并行任务,这真的有什么大不了的吗?如果预期的并行度小于默认的线程池大小(无论是什么),我可以安全地忽略该标志吗?最糟糕的情况是,线程池可能会在几百毫秒内缺少线程?

线程池背后的整个想法是创建任务需要几毫秒,因为它要求操作系统创建它,切换上下文等等。。。所以为了解决这个问题,框架创建了一些池,并将使用过的线程保留在那个里供以后使用

您是对的,LongRunning标志很可能会导致创建新线程。。。当新任务需要更长的时间并且线程创建时间不重要时,这是有意义的

Threadpool有特定的算法,如果您从那里集中获取大量线程并让它们保持忙碌,它可能会决定将线程数量增加一倍 假设你要接受越来越多的。。。所以,如果您要让线程池中的线程足够长的时间处于忙碌状态,您将不会从线程池中获得任何好处,而是会得到一些开销


因此,忽略该标志不会破坏任何东西,但可能会带来一些开销。

在调用该方法而不传递
TaskCreationOptions
参数时,默认情况下会忽略
LongRunning
标志,因此您可以放心地假设忽略它是安全的。实际上,省略它比包含它更安全,因为这个标志是作为一种性能优化技术,而不是作为日常商品

一般来说,除非你真的需要它,否则不要使用它。如果通过性能测试发现不使用它会导致处理其他工作的长时间延迟,则通常只使用
LongRunning

如果
ThreadPool
由于其线程被误用(在等待I/O操作完成时被阻塞)而经常处于饥饿状态,则不要使用
LongRunning
标志来装饰所有
任务,一个更简单、更有效的解决方法是在应用程序初始化期间使用该方法增加
ThreadPool
线程的最小数量。例如:

ThreadPool.SetMinThreads(workerThreads: 100, completionPortThreads: 5);

当您重构应用程序以正确使用异步时,撤销此黑客行为将更容易,而不是撤销代码中任何地方的
LongRunning
标志。

如果忽略它,它不会完全中断,但如果您使线程池饱和,则可能需要更长的时间才能启动额外的线程来处理新任务。是否有不想传递此值的原因?总是当我看到人们问“我想避免做X,安全吗?”时,我的直接问题总是“你为什么要避免做X?”。
在实践中会导致TPL启动一个专用线程
-从你的链接中解释说不会。也可能在第3项中讨论了
LongRunning
。@GSerg您引用的链接与OP的说法并不矛盾,即目前TPL通过旋转一个专用线程来尊重
LongRunning
标志。只是不能保证这种行为会永远保持不变。微软有一天会修改这一已有十年历史的API的行为,这种可能性谁也猜不到。我的猜测是:概率很低。当你问“我可以安全地忽略这个标志吗”你的意思是“我可以安全地忽略这个标志吗”@TheodorZoulias确实纠正了这一点,它的推论是,在一个小应用程序中,我们不使用很多线程或性能根本不是问题,它是安全的,但也许应该这样评论/记录。或者我们只是用“正确”的方式。