У меня есть веб-приложение, и я использую много асинхронных операций, используя async/wait. Все работало нормально, но когда я создавал пользовательские задачи для параллельной работы нескольких вещей, я заметил, что в рамках этой задачи текущая культура меняется после ожидания. Проблема заключается в том, что threadpool использует культуру операционной системы, которая отличается от культуры запроса и что синхронизация по умолчанию не обновляет культуру даже при изменении культуры текущего потока в задаче.
Итак, я создаю настраиваемый контекст синхронизации:
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-культура де-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 и ждут, или задачи хороши или нет в моей ситуации.