2014-07-03 45 views
4

考虑下面的代码在调用异步异步方法和的TaskScheduler /伺机

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方法 - 将使用哪个TaskScheduler?它会使用默认还是传递给父任务的参数?

+1

选项2从来没有开始一个线程? –

+1

@亨克它启动并执行 – Boris

+0

但不是在一个线程。 –

回答

3

在一般情况下,虽然,“选项1”将创建一个新的任务一个包装调用foo(),有效地使一个Task<Task<int>>。当你打电话给.Wait()时,它不会等待内部任务完成,因为内部任务将立即返回(只要Task.Delay)就会被触发。

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

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

+0

你说await会使用用于创建foo的自定义调度器吗? – Boris

+0

@Boris否,但'Task.Factory.StartNew'将使用您的调度程序,这可能会或可能不会真正开始“任务”:) –

+0

对不起,...我完全困惑:(据我了解如果我有async方法,它使用内部等待,编译器有效地创建包含方法部分作为单独任务的任务链。现在,我怎样才能确保每个这些任务都使用我的自定义任务调度程序来调度? – Boris