如何正确使用Task.ContinueWith,使其在线程池线程上运行

时间:2019-07-09 13:54:55

标签: c# asynchronous async-await task

我最近阅读了这篇博客文章:ContinueWith is Dangerous, Too,其中指出:

  

不幸的是,我看到开发人员在   Task.ContinueWith。 StartNew的主要问题之一是它具有   令人困惑的默认调度程序。这个完全相同的问题也存在于   ContinueWith API。就像StartNew一样,ContinueWith将默认为   TaskScheduler.Current,而不是TaskScheduler.Default。

我认为我有一个有效的用例,可以使用ContinueWith而不是使用await:

tasks.Add(database.Table<Table1>().ToListAsync().ContinueWith(sender =>
{
    //some algorithm here
});
tasks.Add(database.Table<Table2>().ToListAsync().ContinueWith(sender =>
{
    //some algorithm here
});
await Task.WhenAll(tasks).ConfigureAwait(false);

现在从以上博客文章中,我认为正确的使用方法是:

tasks.Add(database.Table<Table1>().ToListAsync().ContinueWith(sender =>
{
    //some algorithm here
}, TaskScheduler.Default);
tasks.Add(database.Table<Table2>().ToListAsync().ContinueWith(sender =>
{
    //some algorithm here
}, TaskScheduler.Default);
await Task.WhenAll(tasks).ConfigureAwait(false);

这正确吗?

上面的代码是否意味着ContinueWith现在将在ThreadPool线程上运行?

TaskScheduler.Current,TaskScheduler.Default TaskScheduler.FromCurrentSynchronisationContext()

有什么区别?

1 个答案:

答案 0 :(得分:0)

是的,您可以找到确认here

指定要使用默认任务计划程序,它将使用ThreadPool。

  

默认任务计划程序基于.NET Framework 4线程池,该线程池提供了工作负载窃取以实现负载平衡,线程注入/引退以实现最大吞吐量以及总体上良好的性能。对于大多数情况来说应该足够了。

正如 d.moncada 所指出的,存在一个类似的问题,其回答非常好here