У нас есть приложение ASP.NET, которое ставит в очередь некоторые из своих длительных операций (например, генерирует отчеты) в ThreadPool
с использованием System.Threading.ThreadPool.QueueUserWorkItem
.
У нас есть две проблемы с этим подходом:
Мы запускаем пул приложений ASP.Net с использованием определенной учетной записи службы домена, чтобы он мог обращаться к удаленным ресурсам, включая файлы и базы данных. Когда выполнение начинается в ThreadPool, для идентификатора пользователя потока устанавливается значение Сетевая служба, что не позволяет нам получать доступ к удаленным ресурсам.
Доступ к веб-приложению может одновременно осуществляться пользователями в разных странах, а формат данных, которые мы предоставляем каждому пользователю, основан на их настройках культуры (с использованием стандартных настроек глобализации в web.config). Когда поток в очереди запущен, он также теряет эту информацию и возвращается к стандартному языку операционной системы.
Теперь мы, вероятно, можем обойти большинство из этих проблем, захватив текущую идентификацию пользователя и культуру в объекте состояния и передав ее фоновому работнику, затем выдав себя за пользователя и установив культуру в потоке, но это похоже на очень «нечистый» способ решить эту проблему.
Есть ли лучший способ?
Дополнительная информация:
Вот настройки глобализации от web.config
:
<globalization requestEncoding="utf-8" responseEncoding="utf-8" culture="auto" enableClientBasedCulture="true" uiCulture="auto"></globalization>
Когда запрос обрабатывается, ASP.NET автоматически устанавливает Culture
и UICulture
текущего потока в соответствии с запрашиваемой культурой пользователя (которая автоматически передается браузером в заголовке Accept-Language
).
Это поведение можно повторить, добавив следующий код практически к любому событию в коде позади (например, нажатие кнопки, загрузка страницы и т. Д.):
' Called from just about anywhere
ThreadInitiator()
Private Sub ThreadInitator()
' Observe the culture and windowsidentity here; they will be correct
System.Threading.ThreadPool.QueueUserWorkItem(AddressOf Testing, new Object)
End Sub
Private Sub Testing(state As Object)
' Observe the culture and windowsidentity here; they will not be what we need them to be
End Sub