2014-09-26 150 views
1

我正在處理使用ASP.NET成員資格的WPF應用程序中的問題& SQL Anywhere的角色提供程序。該應用使用BackgroundWorker對象在UI線程背景中執行任務。簡而言之:何時創建線程池?

  1. 在程序啓動時,該應用程序允許用戶登錄
  2. 一旦用戶登錄,它會創建一個自定義的User類的一個實例。這個類實現了IPrincipal接口。
  3. 一旦自定義User類的實例被創建,它將被傳遞給AppDomain.SetThreadPrincipal方法,以便創建的每個新的Thread都將其用作默認Principal
  4. 後臺任務使用Thread.CurrentThread.Principal屬性來確定當前登錄的用戶的名稱並從Role提供程序檢索用戶的權限。

這種機制已經運行良好3年,但最近發生了一些變化。我們已經升級了許多第三方庫,現在BackgroundWorker線程正在使用默認的Principal,它具有空字符串作爲用戶名。這意味着當執行角色檢查並且後臺任務不工作時,不會從數據庫中檢索數據。

所以看起來線程池中的線程正在被創建得比他們以前在最近的升級之前更早。我想知道它們何時創建,以便我可以調查在啓動之前執行用戶登錄過程的可能性。

.NET在什麼時候創建線程池及其內部的線程?

+0

.net線程池是一個靜態訪問,一旦CLR加載進程(mscoree.dll)就加載,它一直是這樣的,實際上這是針對所有機器範圍內的CLR實例。在這種情況下,您可能想調試的問題是當BackgroundWorker訪問Membership API以獲取用戶名時發生的情況,最有可能的問題就是在那裏。您可能需要添加一些日誌記錄來確定訪問Membership API時會發生什麼情況。 – 2014-09-26 13:15:22

+0

線程池在程序啓動時創建。一些池線程在啓動時創建,但其他的則根據需要按需創建。請參閱http://msdn.microsoft.com/en-us/library/system。threading.threadpool(v = vs.110).aspx – 2014-09-26 16:19:00

回答

0

儘管我無法確定線程池何時啓動,但我可以確認它可以從Application.Startup事件中獲得,這是WPF應用程序中引發的第一個事件。這是容易測試。在App.xaml添加一個處理此事件並運行它Task

<Application x:Class="Midas.App" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Startup="App_Startup"> 
    ... 
</Application> 

...

public void App_Startup(object sender, StartupEventArgs e) 
{ 
    Task startupTask = new Task(() => SomeMethod()); 
} 

如果調用SomeMethod作品,那麼線程池工作,因爲Task庫使用它在下面。從The Managed Thread Pool MSDN上的頁面:

從.NET Framework 4開始,使用線程池的最簡單方法是使用任務並行庫(TPL)。默認情況下,並行庫類型(如Task和Task)使用線程池線程來運行任務。

+0

因此,看起來線程池可以在程序加載後立即使用。沒關係。但是,它什麼時候創建了構成它的線程呢?如果線程池類一旦被CLR加載,那麼爲什麼在最近的升級之前,相同的代碼在'Tread.CurrentPrincipal'屬性中具有正確的主體,但是在升級之後沒有? – 2014-09-26 13:26:31

+0

@TonyVitabile它根據需要創建它們。如果ThreadPool在足夠長的時間內完成工作,它將非常緩慢地創建新線程。最初的一堆('ThreadPool.MinXXXThreads')是由線程池本身創建的。 – Luaan 2014-09-26 13:34:05

+0

@Luaan:我設法在'Thread.SetCurrentPrincipal'方法上添加了一個跟蹤點,並且發現在我的代碼設置AppDomain的方法之前,程序以'GenericPrincipal'作爲參數開始時確實會創建大量線程線程負責人。但是,我無法確定該調用是從哪裏進行的,因爲它是從本機到受管理的轉換調用的(調用堆棧中唯一的東西就是對該方法的調用)。我需要考慮在AppDomain的Thread Principal被設置爲我的主體時解決這個問題;更改init命令可能並不總是有效。 – 2014-09-26 15:27:41