2009-06-09 13 views
0

我在應用程序的WinForm.in中有一個標籤,我爲 創建了一個線程來設置標籤的Text屬性。 因爲負責制定 標籤的Text屬性的代碼是另一個線程,我寫的是這樣的:爲什麼我的代碼設置標籤文本有時不能正確調用?

private void SetLabel8Text(string text) 
    { 
     try 
     { 
      if (this.label8.InvokeRequired) 
      { 
       SetTextCallback d = new SetTextCallback(SetLabel8Text); 
       this.Invoke(d, new object[] { text }); 
      } 
      else 
      { 
       this.label8.Text = text; 
      } 
     } 
     catch (Exception ex) 
     { 

     } 

    } 

現在,我還處理KeyPress事件,像這樣:

if (e.KeyChar.ToString() == "\r") 
      { 
     SetLabel8Text("Enter key Pressed !"); 
    } 

的我面臨的問題是,在按下Enter鍵(KeyPress事件執行 )之後,SetLabel8Text方法永遠不會被執行。

一切似乎很好地流動, 我嘗試逐步執行代碼,並在這個地方掛(該SetLabe8Text方法中:

this.Invoke(d,新的對象[] {文本});

它掛起,不往前走一點

+1

你可能會得到更好的答案與更具描述性的標題。 – driis 2009-06-09 18:29:18

+0

寫了更多描述性標題。 – 2009-06-09 18:33:18

回答

0

嘗試以下操作:

if(e.KeyChar == '\n') 
    SetLabel8Text("Enter key Pressed !"); 
4

那麼事實上你是燕子由SetLabel8Text拋出的任何異常都很難確切地知道發生了什麼。你應該從來沒有無條件吞下異常,沒有至少記錄發生了什麼事情。 (你也不應該只是捕捉「異常」,趕上一個更具體的例外類型)。你可以發佈一個簡短但完整的程序來證明問題。

在按鍵事件中添加日誌記錄和SetLabel8Text也有幫助。

0

嘗試:

if (e.KeyCode == Keys.Enter) { 
} 
1

嘗試調用BeginInvoke代替Invoke

Invoke是一個阻塞呼叫,所以有可能你有競爭條件。 (Invoke只有在該方法實際執行時纔會返回,但該方法只能在UI線程處理其消息循環後才能執行)。

0

一個可能的解釋可能是你接下來要做的事情。假設在另一個線程中調用SetLabel8Text函數,它將需要調用,並因此再次執行。但是,它第二次執行(因此不需要調用)它在擁有GUI的線程中執行,通常是主線程。所以如果你的代碼在你的應用程序的其他地方有一段時間阻塞了主線程,那麼看起來像SetLabel8Text函數從來沒有被執行第二次。總是線程繁重的任務,並保持主線程爲簡單閒置。

0

你沒有遵循winforms的基本原則:只在UI線程上創建UI控件。您的KeyPress事件的事件處理程序位於UI線程上,因此,如果您的標籤是在UI線程上創建的,則無需在其上使用BeginInvoke/Invoke。

如果您在UI線程以外的線程中創建窗體,控件等,那麼您可能會做錯某些事情。

請參閱:http://weblogs.asp.net/justin_rogers/pages/126345.aspx爲血淋淋的細節。

相關問題