Ian Vink
Ian Vink

Reputation: 68780

DefaultThreadCurrentCulture in ASP.NET MVC 5 Full Request

In our ASP.NET MVC 5 project we set the Culture of the main thread based on the value of a cookie so that the full Request is run under the same culture.

We'd like to start using the Async support. If we set the DefaultThreadCurrentCulture when the Request starts, will this cause all threads on this, and only this, Request to run as the defined culture?

The site gets a lot of traffic so I am worried that if I use DefaultThreadCurrentCulture that it will affect other user's as their Requests come in at the same instant.

 My BaseController
   {
    protected override IAsyncResult BeginExecuteCore(AsyncCallback callback, object state)
    {
        string defaultCulture = "fr-CA"; //From Cookie in reality

        // Modify current thread's cultures            
        Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(cultureName);
        Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;
        Thread.CurrentThread.DefaultThreadCurrentCulture= Thread.CurrentThread.CurrentCulture;
        Thread.CurrentThread.DefaultThreadCurrentUICulture= Thread.CurrentThread.CurrentCulture;

        return base.BeginExecuteCore(callback, state);
    }
   }

Upvotes: 1

Views: 1466

Answers (1)

Brent Arias
Brent Arias

Reputation: 30195

I have bad news, good news, and bad news.

Bad News

First, the new 4.5 properties DefaultThreadCurrentCulture and DefaultThreadCurrentUICulture apparently are global settings rather than per-request settings. Notice the reflected code shows no signs of ExecutionContext or CallContext:

    [__DynamicallyInvokable]
    public static CultureInfo DefaultThreadCurrentCulture
    {
        [__DynamicallyInvokable]
        get
        {
            return CultureInfo.s_DefaultThreadCurrentCulture;
        }
        [__DynamicallyInvokable]
        [SecurityPermission(SecurityAction.Demand, ControlThread=true)]
        [SecuritySafeCritical]
        set
        {
            CultureInfo.s_DefaultThreadCurrentCulture = value;
        }
    }

    [__DynamicallyInvokable]
    public static CultureInfo DefaultThreadCurrentUICulture
    {
        [__DynamicallyInvokable]
        get
        {
            return CultureInfo.s_DefaultThreadCurrentUICulture;
        }
        [__DynamicallyInvokable]
        [SecurityPermission(SecurityAction.Demand, ControlThread=true)]
        [SecuritySafeCritical]
        set
        {
            if (value != null)
            {
                CultureInfo.VerifyCultureName(value, true);
            }
            CultureInfo.s_DefaultThreadCurrentUICulture = value;
        }
    }

Good News

Fortunately, the custom ASP.NET AspNetSynchronizationContext apparently handles CultureInfo so that it does flow between threads as you would hope.

However...

Bad News

There was a bug identified with AspNetSynchronizationContext which, if it is still unfixed, suggests the mechanism to "flow" CultureInfo might be unstable.

Upvotes: 2

Related Questions