等待任务分配和不分配

时间:2018-12-04 09:02:38

标签: c# async-await

考虑一些功能:

private async Task LittleFunction()
{
  var operand = new SomeObject();
  var notUsedResult =  await SomeAsyncOperationWith(operand); // 1
  // OR
  await SomeAsyncOperationWith(operand); // 2
  SomeOtherOperationsWith(operand); 
}

1 2 之间有区别吗?我知道可以使用的上下文和其他任务属性,但是现在我对状态机行为的差异很感兴趣。谢谢。

3 个答案:

答案 0 :(得分:3)

这两种方法没有明显的区别,如果有什么区别,它们会导致相同的IL,但是您可以使用.net反汇编程序为自己证明这一点。

我认为这个问题更有趣的地方是

  

但是现在我对状态机行为的差异很感兴趣。

状态机的工作方式是一个实现细节,并且可能会因版本而异(并且自"my_number = parsed["totalNumRecs"] KeyError: 'totalNumRecs'" 首次实现以来发生了很大变化)。

您应该关注的是您的环境,如果您遇到性能问题,则应使用探查器或基准框架,而不要再猜测CLR和Jitter的内部情况

答案 1 :(得分:2)

这两者之间没有区别;尽管如果您不需要赋值,我认为最好跳过赋值以提高可读性(即,如果方法比上面的简单示例具有更多的功能,通过不引入新变量,那么就没有人需要精神上的跟踪了) notUsedResult(尽管您的命名无论如何都做得很好)。

// 1
private async Task LittleFunction()
{
  var operand = new SomeObject();
  var notUsedResult =  await SomeAsyncOperationWith(operand); 
  SomeOtherOperationsWith(operand); 
}

// 2
private async Task LittleFunction()
{
  var operand = new SomeObject();
  await SomeAsyncOperationWith(operand); 
  SomeOtherOperationsWith(operand); 
}

但是,还有第三种选择:

// 3
private async Task LittleFunction()
{
  var operand = new SomeObject();
  var task = SomeAsyncOperationWith(operand); 
  SomeOtherOperationsWith(operand); 
  await task;
}

这与上面的不同之处在于,SomeAsyncOperationWithSomeOtherOperationsWith之前被调用,但是直到之后才被完成。如果两个任务之间没有依赖性,则更好,因为它允许函数在等待SomeOtherOperationsWith中正在进行的任何IO /长时间运行操作时执行SomeAsyncOperationWith逻辑(即,这样做的好处是首先使用async。当然,如果在SomeAsyncOperationWith之前需要完成SomeOtherOperationsWith任务是有依赖性的,则需要坚持使用原始解决方案之一。

答案 2 :(得分:1)

SomeAsyncOperationWith(operand);实现负责创建Task,安排在适当的时间无法立即完成的所有工作,并决定何时标记{{ 1}},它将返回“已完成”,“已取消”或“故障”。

它既不知道也不在乎使用返回的TaskTask最终包含的Result的任何调用方法 。 / p>

关于“状态机”的任何信息(如果甚至存在)都不会暴露给调用者。