使用C#中的TPL与async / await / result的不一致

时间:2017-01-08 19:51:49

标签: c# multithreading asynchronous async-await task-parallel-library

我一直在使用C#中的TPL进行一些测试,以更好地了解如何创建线程以及何时启动新线程。

通过以下测试,第一个使用no from __future__ import print_function 的行为符合预期,并始终返回我期望的值。但是,使用async/await的最后2个测试非常不一致。

在我的测试中,我做了以下假设:

    由于任务正在完成,
  1. async/await将返回同一个线程。
  2. 由于延迟不会立即返回,
  3. GetThreadIdInstant将返回不同的线程。
  4. 由于使用了GetThreadIdDelayed。,
  5. GetThreadIdForcedNew会在不同的主题上返回

    对于在任务中使用Task.Run()时,为什么上述假设为真,是否有解释,但在使用.Result时却不一致?

    编辑:关于“不一致”测试的澄清:所以使用async/await的最后2个测试,我仍然期望它们使用async/await给出与第一个测试相同的结果,这不是真的。但是,我在.Result循环中包含代码的原因是某些迭代有效,然后我的for语句将失败。我使用“不一致”一词的原因是b / c连续运行测试,并且只是在运行它们与调试它们之间交替导致它们有时会通过并且有时会失败。

    Assert

1 个答案:

答案 0 :(得分:2)

请在此处查看this answer相关问题。

当你使用.Result ...你正在阻塞当前线程,因此在GetThreadIdDelayed()和GetThreadIdForcedNew()方法中的任务上完成的工作总是在除了调用线程。

当您使用await时...虽然执行不会在调用线程上继续,但在执行子任务期间不会消耗该线程,并且可能(有时)用于执行某些子任务本身的工作。

另请注意,默认情况下,调用await后执行并不总是在同一个线程上返回。这在例如许多UI应用程序中尤为重要。您可以使用ConfigureAwait控制此行为。