According to the answer in this question async/await
call should preserve CurrentCulture. In my case, when I call my own async methods, the CurrentCulture is preserved. But if I call some method of WCF service, CurrentCulture isn't preserved, it's being changed to something that looks like server's default thread's culture.
I've looked at what managed threads are invoked. It happens so that every line of code was executed on a single managed thread (ManagedThreadId stays the same). And CultureInfo stays the same after a call to my own async method. But when I call a WCF's method, ManagedTrheadId stays the same, but CurrentCulture is changed.
The simplified code looks like this::
private async Task Test()
{
// Befoe this code Thread.CurrentThread.CurrentCulture is "ru-RU", i.e. the default server's culture
// Here we change current thread's culture to some desired culture, e.g. hu-HU
Thread.CurrentThread.CurrentCulture = new CultureInfo("hu-HU");
var intres = await GetIntAsync();
// after with await Thread.CurrentThread.CurrentCulture is still "hu-HU"
var wcfres = await wcfClient.GetResultAsync();
// And here Thread.CurrentThread.CurrentCulture is "ru-RU", i.e. the default server's culture
}
private async Task<int> GetIntAsync()
{
return await Task.FromResult(1);
}
The wcfClient
is an instance of auto generated WCF client (inheritor of System.ServiceModel.ClientBase
)
This all happens in ASP.NET MVC Web API (self-hosted), I use Accept-Language header to set CurrentCulture to access it later and use it to return localized resources. I could move along without CurrentCulture and just pass CultureInfo to every method, but I don't like this approach.
Why CurrentThread's CurrentCulture is changed after a call to WCF service and remains the same after a call to my own async method? Can it be "fixed"?
GetIntAsync
to:await Task.Delay(100); return 1;
? – ComfortableAspNetSynchronizationContext
when your code continues on a different thread afterawait
. You could work it around with a customer awaiter like Stephen Toub'sCultureAwaiter
from here: blogs.msdn.com/b/pfxteam/archive/2011/01/13/10115642.aspx – DelineatorAspNetSynchronizationContext
when there is a thread switch, verified. So it has to be something insidewcfClient.GetResultAsync()
. – DelineatorAspNetSynchronizationContext
for self-hosted Web API runtime. See Stephen's comments to my answer. – Delineator