9

I have an MVC app where I override my base controller's OnActionExecuting() method to set my thread culture:

protected override void OnActionExecuting(ActionExecutingContext filterContext) {
    var langCode = GetLangCode();
    Thread.CurrentThread.CurrentUICulture = new CultureInfo(langCode);
    Thread.CurrentThread.CurrentCulture = new CultureInfo(langCode);
}

As I have started to program asynchronously more, I'm curious about how culture is persisted if we return the thread whose culture we've modified to the thread pool, and a new thread is dispatched when the async task completes? Any gotchas I should be aware of?

Mister Epic
  • 16,295
  • 13
  • 76
  • 147
  • Won't the next request being handled by that thread take a trip through `OnActionExecuting` as well? – Lasse V. Karlsen Jan 29 '15 at 18:04
  • @LasseV.Karlsen Each request should execute `OnActionExecuting`, but can't each request be serviced by multiple threads? If in my data access layer I use an asynchronous model to communicate with the database, could I not get two separate threads for the course of the request, one where culture has been modified, the other where it hasn't? – Mister Epic Jan 29 '15 at 18:09
  • 1
    That seems possible, don't know enough about this, sorry. Any chance you're using .NET 4.5? If so, have a look at [CultureInfo.DefaultThreadCurrentCulture](https://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo.defaultthreadcurrentculture%28v=vs.110%29.aspx) – Lasse V. Karlsen Jan 29 '15 at 18:10

2 Answers2

8

A major gotcha might be using the await task.ConfigureAwait(false) pattern, which is often misused as an easy (but wrong) remedy against deadlocks. This way, the continuation would happen on a pool thread without synchronization context. In this case, CurrentCulture won't be flowed, because it doesn't get flowed as a part of ExecutionContext. Even worse, you might be using Task.Run(lambda) (which normally you shouldn't in an ASP.NET application). The code inside lambda will not have the correct CurrentCulture.

Otherwise, AspNetSynchronizationContext will correctly flow CurrentCulture across await continuations, even though they happen on different threads.

noseratio
  • 59,932
  • 34
  • 208
  • 486
3

In short, yes ASP.NET is configured to flow things like culture across your asynchronous operations via a SynchronizationContext. You can read a bit about how it works on MSDN: https://msdn.microsoft.com/en-us/magazine/gg598924.aspx

There are some gotchas related to identity that you can read about on this SO question: Using ASP.NET Web API, my ExecutionContext isn't flowing in async actions

Community
  • 1
  • 1
Brandon
  • 38,310
  • 8
  • 82
  • 87