using ThreadStatic variables with async/await

后端 未结 5 990
独厮守ぢ
独厮守ぢ 2020-12-08 19:21

With the new async/await keywords in C#, there are now impacts to the way (and when) you use ThreadStatic data, because the callback delegate is executed on a different thre

5条回答
  •  误落风尘
    2020-12-08 20:11

    Getting a task continuation to execute on the same thread requires a synchronization provider. That's an expensive word, the simple diagnostic is by looking at the value of System.Threading.SynchronizationContext.Current in the debugger.

    That value will be null in console mode app. There is no provider that can make code run on a specific thread in a console mode app. Only a Winforms or WPF app or ASP.NET app will have a provider. And only on their main thread.

    The main thread of these apps do something very special, they have a dispatcher loop (aka message loop or message pump). Which implements the general solution to the producer-consumer problem. It is that dispatcher loop that allows handing a thread a bit of work to perform. Such a bit of work will be the task continuation after the await expression. And that bit will run on the dispatcher thread.

    The WindowsFormsSynchronizationContext is the synchronization provider for a Winforms app. It uses Control.Begin/Invoke() to dispatch the request. For WPF it is the DispatcherSynchronizationContext class, it uses Dispatcher.Begin/Invoke() to dispatch the request. For ASP.NET it is the AspNetSynchronizationContext class, it uses invisible internal plumbing. They create an instance of their respective providers in their initialization and assign it to SynchronizationContext.Current

    There's no such provider for a console mode app. Primarily because the main thread is entirely unsuitable, it doesn't use a dispatcher loop. You would have create your own, then also create your own SynchronizationContext derived class. Hard to do, you can't make a call like Console.ReadLine() anymore since that entirely freezes the main thread on a Windows call. Your console mode app stops being a console app, it will start resembling a Winforms app.

    Do note that these runtime environments have synchronization providers for a good reason. They have to have one because a GUI is fundamentally thread-unsafe. Not a problem with the Console, it is thread-safe.

提交回复
热议问题