-1

I am facing a problem with the async main feature of c# 7.1.

Here is a github link to a sample project to demonstrate the problem: https://github.com/xorpherion/CSharpAsyncMainProblem

The code is used as part of a gameloop. As you can see the main signature uses async so behind the scenes a synchronization context is created.

The Timedloop class is kind of a timer that tries to schedule an event (OnTick) when the current time exceeds a limit. There are 3 methods to trigger the event: SpinLoop, WaitLoopAsync and WaitLoop. SpinLoop and WaitLoop behave as expected ( single threaded scheduling of OnTick). The problem lies with WaitLoopAsync. What i am expecting here is to also stay on the current thread as .ConfigureAwait is not set to "false". But when you run the code you will see messages on the console that the thread id changes. This does not happen with the other loop "types".

My question here: Why is the continuation not scheduled on the same thread?

I am running this on .net core 2.1.

Nogiax
  • 35
  • 2
  • 8
  • 2
    Please see [Should a question that is meaningless without viewing an external link be closed?](https://meta.stackoverflow.com/questions/266909/should-a-question-that-is-meaningless-without-viewing-an-external-link-be-closed) and [ask]. – John Wu Aug 11 '18 at 22:32

1 Answers1

8

As you can see the main signature uses async so behind the scenes a synchronization context is created.

No, that's not the case. Awaiting a task will (by default) use a synchronization context if it started in one - but it won't create one automatically. A console app doesn't have any synchronization context normally, so continuations are executed on a thread-pool thread.

If you want a console app to use a synchronization context, you'll need to create one yourself. Stephen Cleary's AsyncEx project contains an implementation; see this Stack Overflow answer for more details usage.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I am specifically using this feature: https://blogs.msdn.microsoft.com/mazhou/2017/05/30/c-7-series-part-2-async-main/ which should behave differently as you are suggesting, right? – Nogiax Aug 11 '18 at 22:12
  • 2
    @Nogiax: Why would it behave differently? As the blog post suggests, an async `Main` method is just syntactic sugar for calling `GetAwaiter().GetResult()`. There's still nothing to create a synchronization context for you implicitly. You can verify this by logging `SynchronizationContext.Current` - I would expect it to be null everywhere. – Jon Skeet Aug 11 '18 at 22:42
  • In an UI app, does `await` ensure that the method resumes on the same UI context, not the same thread? – variable Aug 02 '21 at 17:25
  • @variable: You'd need to specify what kind of UI you mean, and *exactly* what you mean by "UI context" here. – Jon Skeet Aug 02 '21 at 19:31
  • Windows form app ui and the synchronization context – variable Aug 03 '21 at 03:10
  • @variable: You do end up in the right synchronization context (which means also in the UI thread). – Jon Skeet Aug 03 '21 at 07:10