异步主c#7.1中的线程切换

Nog*_*iax -1 c# async-await

我遇到了c#7.1的异步主要功能问题.

这是一个示例项目的github链接,用于演示此问题:https://github.com/xorpherion/CSharpAsyncMainProblem

该代码用作游戏循环的一部分.正如您所看到的,主要签名使用异步,因此在幕后创建了同步上下文.

Timedloop类是一种计时器,它尝试在当前时间超过限制时安排事件(OnTick).有3种方法可以触发事件:SpinLoop,WaitLoopAsync和WaitLoop.SpinLoop和WaitLoop按预期运行(OnTick的单线程调度).问题出在WaitLoopAsync上.我在这里期待的是也保持当前线程为.ConfigureAwait未设置为"false".但是当您运行代码时,您将在控制台上看到线程ID更改的消息.其他循环"类型"不会发生这种情况.

我的问题是:为什么延续没有安排在同一个线程上?

我在.net核心2.1上运行它.

Jon*_*eet 7

正如您所看到的,主要签名使用异步,因此在幕后创建了同步上下文.

不,事实并非如此.等待任务将(默认情况下)使用同步上下文(如果它在一个中启动) - 但它不会自动创建一个.控制台应用程序通常没有任何同步上下文,因此在线程池线程上执行continuation.

如果您希望控制台应用程序使用同步上下文,则需要自己创建一个.Stephen Cleary的AsyncEx项目包含一个实现; 有关详细信息,请参阅此Stack Overflow答案.

  • @Nogiax:为什么行为会有所不同?正如博客文章所建议的,异步Main方法只是调用GetAwaiter()。GetResult()的语法糖。仍然没有任何内容可以为您隐式创建同步上下文。您可以通过记录`SynchronizationContext.Current`来验证这一点-我希望它在任何地方都为空。 (2认同)