2013-10-24 109 views
0

我有一個偶爾掛起的c#winforms應用程序,我被告知我們應該確保我們不打開主GUI線程的任何窗口。我啓動了Spy ++並注意到當我們在客戶端會話開始時打開OpenFileDialog時,即使代碼路徑在主GUI線程上運行,該對話框也存在於另一個線程中。爲什麼C#OpenFileDialogs在主GUI線程之外創建?

然後,窗口關閉後,窗口仍然顯示在Spy ++中在工作線程上。即使我們在Open語句中使用OpenFileDialog,也會發生這種情況。因此,處理對話似乎並沒有真正擺脫窗口,這很奇怪。

下面是實際的代碼

   if (filename == String.Empty) 
      { 
       using (var openFileDialog = new OpenFileDialog 
        { 
         Filter = string.Format(MessageStrings["DialogFormat"]), 
         Title = MessageStrings["OpenDialogTitle"] 
        }) 
       { 
        if (openFileDialog.ShowDialog() != DialogResult.OK || openFileDialog.FileName == String.Empty) 
         return false; 
        filename = openFileDialog.FileName; 
       } 
      } 
+0

請發表實際的代碼。這似乎不大可能。 – BartoszKP

+0

您的用戶界面線程是否標記了STAThread屬性? – Reda

+0

我懷疑這個對話框會成爲你的問題。它應該是所有的本地代碼。 – David

回答

3

沒有,對話肯定是在正常使用的UI線程擁有。我沒有看到您使用Spy ++時報告的證據。我在這裏寫了幾個答案,以便在UI線程擁有對話框窗口時只能使用對話框的技巧。請注意,OpenFileDialog會創建大量的窗口,因此在Spy ++視圖中很容易迷路。在關閉對話框後看到窗口仍然存在,否則很容易解釋,您必須使用Window + Refresh來強制Spy ++更新快照。

看到由另一個線程擁有的對話不是你的UI線程,否則就是你試圖調試的麻煩。在不是STA的線程上運行它們時,shell對話框會變得很脆弱。有時你會得到一個異常,但並不一致。沒有出現的對話確實是一種明顯的可能性,我已經看到了這種情況。使用調試器的Debug + Windows + Threads來查看調用堆棧以找出發生這種情況的原因。

啓用非託管調試可以讓您看到更多,但請注意shell對話框本身會添加大量線程。你將所有的shell擴展加載到你的進程中,他們有一個運行自己線程的訣竅。這些擴展本身就是一個長期的麻煩來源,使用SysInternals的Autoruns來禁用它們進行診斷。

+0

我們只有四個線程有窗口。主要的UI線程有幾百個字。然後是我在這個問題中描述的那個。然後再有兩個關於「Default IME」的內容。我甚至可以得到那些Winforms應用程序中最簡單的窗口,所以我認爲這些都可以。接下來,我們將從這個答案中嘗試漢斯的建議。 –

相關問題