Я работаю над проектом ASP.NET Web API, в котором у меня возникла проблема, когда дочерние Task
, которые работают асинхронно, не наследовали текущую культуру родительского потока; то есть даже после установки Thread.CurrentThread.CurrentUICulture
в конструкторе контроллера любой Task
, созданный в действии, имел инвариантную культуру по умолчанию, если я не установил его отдельно. Кажется, это исправлено в framework> 4.0 и работало нормально после обновления целевой платформы с 3.5.2
до 4.6.2
, как упоминалось здесь .
Начиная с приложений, нацеленных на .NET Framework 4.6, культура вызывающего потока наследуется каждой задачей, даже если задача выполняется асинхронно в потоке пула потоков.
Теперь, когда культурное наследование в Задачах работает должным образом, я столкнулся с еще одной странной проблемой, которой не было , отсутствующей в 4.5.2 . Если результат действия WebApi имеет тип IEnumerable
, то в нем будет культура по умолчанию. Может быть, проблему можно было бы лучше объяснить, используя пример кода:
public SampleController()
{
System.Threading.Thread.CurrentThread.CurrentUICulture =
new System.Globalization.CultureInfo("ar-AE");
}
[Route]
public IHttpActionResult Get()
{
IEnumerable<Employee> employeesDeferred = BuildEmployees(true);
return Ok(employeesDeferred);
}
private IEnumerable<Employee> BuildEmployees(bool isDeferred)
{
var employees = Enumerable.Range(0, 2)
.Select(count => new Employee
{
Id = count++,
Culture = Thread.CurrentThread.CurrentUICulture.Name
});
if (isDeferred) { return employees; }
return employees.ToList();
}
Обратите внимание, что я устанавливаю культуру пользовательского интерфейса как "ar-AE" в конструкторе. PFB результаты:
- framework 4.5.2 -
Culture
всех сотрудников будет ar-AE, как и ожидалось
- framework 4.6.2 -
Culture
всех сотрудников будут в США (по умолчанию)
- framework 4.6.2, выполнив
.ToList()
в результате (вызов BuildEmployees(false)
вместо BuildEmployees(true)
в приведенном выше коде) - Culture
всех сотрудников будет ar-AE, как и ожидалось
Я провел некоторое исследование и увидел ответы, в которых предлагается установить переключатель NoAsyncCurrentCulture
, например, добавив переключатель в настройках приложения <add key="appContext.SetSwitch:Switch.System.Globalization.NoAsyncCurrentCulture" value="true" />
- но это будет своего рода откат к поведению, которое мы имели в <4.0 и вызовет проблему с наследованием культуры в Задачах, как указано в первом параграфе. </p>
Чего мне не хватает?
Обновление: проверено, что культура контекста не наследуется в потоке, где в Web API происходит сериализация (JSON / XML).