【发布时间】:2014-03-08 18:00:14
【问题描述】:
我有一个 Web 应用程序,我通过 async/await 使用了很多异步操作。一切正常,但是当我创建自定义任务以并行运行多个事物时,我注意到,在此任务中,当前文化在等待后会发生变化。问题似乎是,线程池使用操作系统的文化,这与请求的文化不同,并且默认同步不会更新文化,即使在任务中更改当前线程的文化也是如此。
所以我创建了一个自定义同步上下文:
public sealed class CulturePreservingSynchronizationContext : SynchronizationContext
{
private CultureInfo culture;
private CultureInfo cultureUI;
public CulturePreservingSynchronizationContext()
{
GetCulture();
}
public void MakeCurrent()
{
SetCulture();
SynchronizationContext.SetSynchronizationContext(CreateCopy());
}
public override SynchronizationContext CreateCopy()
{
CulturePreservingSynchronizationContext clonedContext = new CulturePreservingSynchronizationContext();
clonedContext.culture = culture;
clonedContext.cultureUI = cultureUI;
return clonedContext;
}
public override void Post(SendOrPostCallback d, object state)
{
base.Post(s =>
{
SetCulture();
d(s);
}, state);
}
public override void OperationStarted()
{
GetCulture();
base.OperationStarted();
}
private void SetCulture()
{
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = cultureUI;
}
private void GetCulture()
{
culture = CultureInfo.CurrentCulture;
cultureUI = CultureInfo.CurrentUICulture;
}
}
你可以这样使用它。在我的简单示例中,它运行良好,但我对评估我的方法的细节没有真正的了解(顺便说一句:我的 os-culture 是 de-DE)。请注意,这只是一个示例,与实际代码无关。我刚刚写了这篇文章来证明等待之后的文化与等待之前的文化是不同的。
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
CulturePreservingSyncContext context = new CulturePreservingSyncContext();
Task.Run(async () =>
{
context.MakeCurrent();
Console.WriteLine(CultureInfo.CurrentCulture);
WebClient client = new WebClient();
string s = await client.DownloadStringTaskAsync(new Uri("http://www.google.de"));
Console.WriteLine(CultureInfo.CurrentCulture);
}).Wait();
非常欢迎任何建议来了解同步上下文的实现是否良好,如果没有,是否有更好的解决方案。如果 async 和 await 或任务在我的情况下是好是坏,我不想展开讨论。
【问题讨论】:
-
可以设置默认线程文化like this。
标签: c# multithreading task-parallel-library