【问题标题】:Calling async method and TaskScheduler in async/await在 async/await 中调用 async 方法和 TaskScheduler
【发布时间】:2014-07-06 16:58:33
【问题描述】:

考虑下面的代码

async Task<int> foo()
{
    await Task.Delay(1000);
    return 42; 
}

...
// OPTION 1

Task t = Task.Factory.StartNew(foo,
            CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);

t.Wait();


...
// OPTION 2
Task t = foo();
t.Wait()

问题

  1. 两种看涨期权的本质区别是什么?

  2. 在选项 1 中。假设我覆盖了默认的 TaskScheduler。对于 foo 方法中的 await - 将使用哪个 TaskScheduler?它会使用默认参数还是传递给父任务的参数?

【问题讨论】:

  • 选项 2 甚至从不启动线程?
  • @Henk 它启动并执行
  • @Henk 我相信至少 Task.Delay 部分将在线程池线程上执行。
  • A Delay() 不需要(占用)线程。

标签: c# asynchronous async-await .net-4.5


【解决方案1】:

不过,一般来说,“选项 1”会创建一个新任务,它将对foo() 的调用包装起来,从而有效地创建一个Task&lt;Task&lt;int&gt;&gt;。当您在其上调用 .Wait() 时,它不会等待内部任务完成,因为内部任务几乎会立即返回(只要Task.Delay 被击中)。

关于您关于使用非默认TaskScheduler 的问题,一般来说,它不会改变行为,除了它可能会阻塞直到自定义调度程序启动任务。如果没有有关相关调度程序的更多信息,就不可能确切知道会发生什么。

然而,第二个选项将阻塞直到延迟完成,因为它将启动任务,并阻塞直到延迟完成。

【讨论】:

  • 你说 await 会使用自定义调度器来创建 foo?
  • @Boris 不,但Task.Factory.StartNew 将使用您的调度程序,它可能会或可能不会真正启动Task :)
  • 对不起,...我完全糊涂了:(据我所知,如果我有在内部使用 await 的异步方法,编译器会有效地创建由方法部分组成的任务链作为单独的任务。现在..如何我可以确保使用我的自定义任务计划程序来计划这些任务中的每一个吗?
  • @Boris 这可能是一个不同的线程,但一次应该只有一个......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-03
  • 1970-01-01
  • 2017-05-13
  • 1970-01-01
  • 2015-04-06
  • 2021-05-02
相关资源
最近更新 更多