2011-06-15 59 views
4

我一直在尋找幾個小時,到目前爲止沒有運氣與這一個 - 所以我想我會發布。在模擬用戶下運行的非UI線程是否自動imersonate UI線程?

我有一個在vb.net上運行的WPF應用程序,運行在DotNet 4.0上,啓動工作線程來執行特定的功能,如哈希文件和其他處理器/時間密集型例程。

某些啓動的線程需要模擬不同的用戶,以便訪問登錄用戶通常無法直接訪問的網絡資源(它們允許通過應用程序控制對網絡資源的訪問,但不能,例如,通過Windows資源管理器)。爲此,工作線程模擬預先確定的具有訪問權限的用戶帳戶,該用戶帳戶允許應用程序訪問網絡資源。

雖然在模擬用戶帳戶下運行此工作線程正在工作 - 它偶爾需要更新坐在用戶目錄中的本地SQL 3.5緊湊型數據庫。這個數據庫只能被登錄用戶訪問 - 而不是模擬用戶。

要允許此更新,從模擬的工作線程我有權訪問UI Dispatcher對象(它在創建線程時通過),其中我調用子例程來更新SQL壓縮數據庫。

這是一個有趣的問題,我無法解釋,但有人可能會解釋這一點。

從工作線程調用UI調度程序的應用程序將退回到登錄用戶憑證以在UI線程中上傳sql數據庫 - 然後當UIthread.dispatcher.invoke調用返回給工作線程時 - 它會回到模擬的工作線程帳戶。

今天 - 我沒有理由 - 當我調用UI調度程序線程來更新SQL Compact數據庫時,線程上下文仍保留在模擬用戶 - 而不是UI線程上的已登錄用戶。它的模擬用戶現在被強加在所有線程上 - 包括UI線程。

我想了解的是什麼是正確的結果 - 如果UIThread.Dispatcher.Invoke在UI線程的用戶上下文中執行任何代碼(未模擬),或者模擬的用戶上下文生效因爲調用回調在UI線程上,因爲它是從工作線程發起的?

我很困惑,因爲昨天 - 當我在UIThread.Dispatcher.Invoked例程中有一個斷點時,我可以看到該線程在登錄用戶帳戶下執行,並且SQL壓縮數據庫的更新工作。然而,今天,相同的代碼在模擬帳戶下執行,並且在嘗試更新數據庫時遇到訪問被拒絕異常。

我在啓動工作線程前檢查了UI線程的ManagedThreadId,並且能夠確認在執行UIThread.Dispatcher.Invoke時的ManagedThreadId返回到UI線程的ManagedThreadId - 然後當調用結束並執行時返回到工作線程的ManagedThreadId返回到正確的工人ManagedThreadId。這一次沒有改變的是該線程的用戶。除非我明確結束模擬線程,否則它現在似乎始終保持在模擬的用戶身上。

有人可以澄清這一點 - 並建議如果我對這一切都做錯了,應該試圖以另一種方式做到這一點。我真正想要了解的是爲什麼它一直在工作 - 爲什麼現在它沒有 - 也沒有 - 沒有代碼在昨天和今天之間更改此代碼。

很抱歉的長期職位

乾杯

杆。

回答

3

你可能想看看線程的執行上下文。

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

從CLR通過C#,3版第721:

在System.Threading命名空間,有一個的ExecutionContext類,允許您控制線程的執行上下文從一個流程線程到另一個。

...

如果發起線程的執行上下文不流向輔助線程,輔助線程將使用任何執行上下文上次與它相關聯。因此,幫助程序線程確實不應該執行任何依賴於執行上下文狀態的代碼(例如用戶的Windows標識)。

此外,我不得不這樣一些模擬在ASP.NET應用程序最近,和中的LogonUser的Win32 API提供了一些非常精細的控制時,我想模仿,我是多麼想模仿(即網絡互動,服務等),然後在單個線程內快速恢復。

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

+1

賓果!主席先生,你是一位天才。在調用調度程序線程之前禁止流程糾正了問題並使其按預期運行。非常感謝 – Roddles 2011-06-15 05:00:16

+0

太棒了!很高興有幫助...乾杯。 – Jason 2011-06-15 05:01:17

+0

我正在使用模擬LogonUser API調用。它的工作很好 - 只是今天出現了這個問題,其中調度UI線程在模擬線程下執行,這個線程幾乎破壞了應用程序的所有方面。明確抑制流量糾正了這個問題,現在又重新開始工作了 - 感謝您的幫助。 – Roddles 2011-06-15 05:16:01