Автоматически лимитирует поток пользовательского интерфейса, выполняемый от имени олицетворенного пользователя, поток пользовательского интерфейса?

Я искал уже несколько часов, и до сих пор мне не повезло с этим - поэтому подумал, что отправлю.

У меня есть приложение WPF, написанное на vb.net, работающее на DotNet 4.0, которое запускает рабочие потоки для выполнения определенных функций, таких как файлы хеширования и другие процедуры с интенсивным процессором / временем.

Некоторым из запущенных потоков необходимо олицетворять другого пользователя, чтобы получить доступ к сетевым ресурсам, к которым зарегистрированный пользователь обычно не может получить доступ напрямую (им разрешен контролируемый доступ к сетевым ресурсам через приложение, но не, например, через проводник Windows) . Для этого рабочий поток олицетворяет заранее определенную учетную запись пользователя, у которой есть доступ, который затем разрешает приложению доступ к сетевым ресурсам.

В то время как этот рабочий поток, работающий под олицетворенной учетной записью пользователя, работает, ему иногда необходимо обновлять локальную компактную базу данных sql 3.5, находящуюся в каталоге Users. Эта база данных доступна только для вошедшего в систему пользователя, но не для олицетворенного пользователя.

Чтобы разрешить это обновление, из олицетворенного рабочего потока у меня есть доступ к объекту UI Dispatcher (он передается при создании потока), в котором я вызываю подпрограмму для обновления компактной базы данных SQL.

Вот интересная проблема, которую я не могу объяснить, но читаю, поскольку кто-то может это объяснить.

Приложение, когда оно вызывало диспетчер пользовательского интерфейса из рабочего потока, возвращалось к учетным данным вошедших в систему пользователей, чтобы обновить базу данных sql в потоке пользовательского интерфейса, а затем, когда вызов UIthread.dispatcher.invoke вернулся в рабочий поток, это было бы обратно в учетную запись олицетворенного рабочего потока.

Сегодня - и у меня нет причин, почему - когда я вызываю поток диспетчера пользовательского интерфейса для обновления базы данных SQL Compact, контекст потока остается у олицетворенного пользователя, а не у пользователя, вошедшего в систему в потоке пользовательского интерфейса. Это похоже на то, что олицетворенный пользователь теперь накладывается на все потоки, включая поток пользовательского интерфейса.

Я пытаюсь понять, каков правильный результат - должен ли UIThread.Dispatcher.Invoke выполнять любой код, вызываемый в пользовательском контексте потока пользовательского интерфейса (не олицетворенный), ИЛИ вступает ли имперсоматизированный контекст пользователя в силу для вызова вызова обратно в поток пользовательского интерфейса, потому что он был инициирован из рабочего потока?

Я озадачен, потому что вчера, когда у меня была точка останова в подпрограмме UIThread.Dispatcher.Invoked, я мог видеть, что поток выполнялся под учетной записью пользователя, вошедшего в систему, и обновления компактной базы данных SQL работали. Однако сегодня тот же код выполняется под олицетворенной учетной записью, и я получаю исключения, запрещающие доступ, при попытке обновить базу данных.

Я проверил ManagedThreadId потока пользовательского интерфейса перед запуском рабочих потоков и могу подтвердить, что ManagedThreadId при выполнении UIThread.Dispatcher.Invoke возвращается к ManagedThreadId потока пользовательского интерфейса, а затем, когда вызов завершается и выполнение возвращается рабочему thread, ManagedThreadId возвращает правильный ManagedThreadId рабочего. Что не меняется на этот раз, так это Пользователь этого потока. Кажется, теперь он остается на олицетворении пользователя все время, если я явно не завершу олицетворение потока.

Может ли кто-нибудь пролить свет на это - и предположить, если я все делаю неправильно и должен ли я попытаться сделать это по-другому. Что я действительно хочу понять, так это то, почему он работает - и почему теперь он не - и нет - никаких изменений кода в этом коде со вчерашнего дня и сегодня.

Простите за длинный пост

Ваше здоровье

Стержень.


person Roddles    schedule 15.06.2011    source источник


Ответы (1)


Возможно, вы захотите взглянуть на контекст выполнения потока.

http://msdn.microsoft.com/en-us/library/system.threading.executioncontext.aspx

Из CLR через C #, 3d ed pg 721:

В пространстве имен System.Threading есть класс ExecutionContext, который позволяет вам контролировать, как контекст выполнения потока перетекает из одного потока в другой.

...

Если контекст выполнения инициирующего потока не передается во вспомогательный поток, вспомогательный поток будет использовать тот контекст выполнения, который он в последний раз связал с ним. Следовательно, вспомогательный поток действительно не должен выполнять какой-либо код, который зависит от состояния контекста выполнения (например, идентификатора пользователя в Windows).

Кроме того, мне недавно пришлось немного подражать в приложении ASP.NET, и Win32 api LogonUser предлагал действительно мелкозернистый контроль, когда я хотел олицетворять, как я хотел олицетворять (например, сеть, интерактивность, сервис и т. Д.), а затем быстро вернуться в один поток.

http://msdn.microsoft.com/en-us/library/ff647404.aspx#paght000023_impersonatingusinglogonuser

person Jason    schedule 15.06.2011
comment
Бинго! Сэр, вы гений. Подавление потока перед вызовом потока диспетчера устранило проблему и заставило его вести себя должным образом. Весьма признателен - person Roddles; 15.06.2011
comment
Потрясающий! Рад, что помог ... Ура. - person Jason; 15.06.2011
comment
Я использую выдачу себя за другое лицо с помощью API-вызова LogonUser. Он отлично работает - именно эта проблема возникла сегодня, когда поток пользовательского интерфейса диспетчеризации выполнялся под олицетворением потока, что нарушало практически все аспекты приложения. Явное подавление потока исправило эту проблему, и теперь она снова работает - спасибо за вашу помощь. - person Roddles; 15.06.2011
comment
Ах ... Спасибо за информацию ... Это отличное обучение через сообщество StackOverflow. Раньше мне не приходилось олицетворять себя в интеллектуальном клиентском приложении, поэтому мне интересно увидеть, как вы используете LogonUser API для этого. - person Jason; 15.06.2011
comment
Я могу опубликовать код для библиотеки олицетворения, которую использую, поскольку он в любом случае был взят из публикации в Интернете. Где я могу разместить пример кода в StackOverflow? - person Roddles; 15.06.2011
comment
О, это даже лучше! Спасибо, @Roddles. Я не уверен в наличии возможности на StackOverflow, но это довольно хороший сервис, который я видел, как люди используют. gist.github.com - person Jason; 15.06.2011
comment
На самом деле - я нашел сайт, на котором реализована гораздо лучшая реализация олицетворения, чем я пользовался, - и для его загрузки была исправлена ​​моя проблема с запуском com-объектов в олицетворенном потоке. Ссылка [ссылка] vbdotnetheaven.com/uploadfile/scottlysle/7407. - person Roddles; 18.06.2011