As Joe pointed out, culture is transferred by the HttpContext
in ASP.NET. The way ASP.NET does this is by installing a SynchronizationContext
when a request starts, and that context is also used to resume asynchronous methods (by default).
So, there are a couple of ways to approach the problem: you can either write your own SynchronizationContext
that will preserve culture by default, or you can explicitly preserve the culture across each await
.
To preserve the culture at each await
, you can use code from Stephen Toub:
public static CultureAwaiter WithCulture(this Task task)
{
return new CultureAwaiter(task);
}
public class CultureAwaiter : INotifyCompletion
{
private readonly TaskAwaiter m_awaiter;
private CultureInfo m_culture;
public CultureAwaiter(Task task)
{
if (task == null) throw new ArgumentNullException("task");
m_awaiter = task.GetAwaiter();
}
public CultureAwaiter GetAwaiter() { return this; }
public bool IsCompleted { get { return m_awaiter.IsCompleted; } }
public void OnCompleted(Action continuation)
{
m_culture = Thread.CurrentThread.CurentCulture;
m_awaiter.OnCompleted(continuation);
}
public void GetResult()
{
Thread.CurrentThread.CurrentCulture = m_culture;
m_awaiter.GetResult();
}
}
The SynchronizationContext
approach is more complicated but once it’s set up, it will be easier to use. I don’t know of a good example of an ASP.NET-like context, but a good starting point is my MSDN article.