2011-11-25 71 views
4

我有一個WPF應用程序,它使用一些庫代碼進行身份驗證,需要在單線程公寓線程中運行。我的方法是產生一個單獨的線程來獲取認證對象,阻塞直到線程返回並繼續執行。但是,在某些實例中,即使線程方法已返回,我的應用程序仍掛在Thread.Join()上。即使線程中的方法已返回,Thread.Join()爲何仍然掛起?

public static ClaimsAuthenticationResult GetClientContextAndCookieCollection(string siteUrl, out CookieCollection cookieResult) 
    { 
     ClaimsAuthenticationResult authResult = new ClaimsAuthenticationResult(); 

     // Authentication module needs to run in single-thread apartment state because it uses 
     // COM library calls where this is required 
     Thread authenticationThread = new Thread(new ThreadStart(threadMethod)); 
     authenticationThread.SetApartmentState(ApartmentState.STA); 
     authenticationThread.Start(); 

     // Block until thread completion 
     authenticationThread.Join(); // Application hangs here 

     return authResult; 
    } 

    private static void threadMethod() { 
     // In proper application: set result. But for debugging, return immediately 
     return; 
    } 

我對於多線程和WPF都是新手,所以我可能會做一些愚蠢的事情。有人看到這裏發生了什麼?爲了記錄,如果我沒有將線程設置爲STA,我不會遇到問題,但這是一項要求。

[編輯:似乎只有當我通過WPF視圖中的驗證綁定調用指定的方法時,特別是在TextBox上纔會出現此錯誤。當我在視圖的構造函數中調用相同的代碼時,代碼按預期運行。這將是一個可行的解決方法,但它會很有趣,知道這裏實際發生了什麼。]

[編輯:這裏的代碼已經簡化了一點調試 - 在生產代碼中,線程方法是在AuthThreadWorker對象,用於將身份驗證過程的結果返回給authResult對象。但是這些細節只要我可以告訴與凍結無關,即使在簡化代碼中凍結也是如此。]

+1

你確定線程的方法已經完成了嗎? –

+0

嘗試附加一個debbuger並在'return'上添加一個斷點檢查你是否真的打了它。如果是這樣,請檢查哪個線程。 – Guillaume

+0

線程方法實際上做了什麼,我沒有看到發佈的代碼有什麼問題? – Jodrell

回答

7

根據您的代碼;它看起來好像你做的是正確的,但線程永遠不會終止。嘗試在線程中函數的END處設置一個斷點;而不是return關鍵字(如果您在return語句中進行某種處理以防止線程退出),如下圖所示 enter image description here。使用authenticationThread.Name(或如示例中所示的mthread.Name)命名線程也可以幫助調試。如果線程完全終止,您應該看到「線程'yourname'(0x143c)已退出,並且代碼爲0(0x0)。」在Visual Studio的輸出窗口中。

+0

+1關於線程名稱的提示。放置在線程方法的最後一個大括號處的斷點實際上被命中,但調試器在通過它時不會報告「線程已退出」。在相同的情況下,調用程序_does_報告「線程退出」時,代碼被我調用而不是WPF。 –

相關問題