C#中控制項的Focus()和GotFocus()的區別?

來源:互聯網
上載者:User
 

問:

f (this.InvokeRequired)            

{                

    this.BeginInvoke(new MethodInvoker(LoadGlobalImage));      

           return;            

}

是什麼意思

 

 

答:

c#中禁止跨線程直接存取控制項,InvokeRequired是為瞭解決這個問題而產生的

當一個控制項的InvokeRequired屬性值為真時,說明有一個建立它以外的線程想訪問它,此時它將會在內部調用new MethodInvoker(LoadGlobalImage)來完成下面的步驟,這個做法保證了控制項的安全,你可以這樣理解,有人想找你借錢,他可以直接在你的錢包中拿,這樣太不安全,因此必須讓別人先要告訴你,你再從自己的錢包把錢拿出來借給別人,這樣就安全了

 

 

another:

在設計中為了讓介面與邏輯分離,我的做法是使用事件,介面只要響應事件來處理介面的顯示就行了。而事件在邏輯處理中可能由不同的線程引發,這些事件的回應程式法在修改介面中的控制項內容時便會引發一個異常。

這時就用到了Control.InvokeRequired 屬性 與Invoke方法。

MSDN中說: 擷取一個值,該值指示調用方在對控制項進行方法調用時是否必須調用 Invoke 方法,因為調用方位於建立控制項所在的線程以外的線程中。 如果控制項的 Handle 是在與調用線程不同的線程上建立的(說明您必須通過 Invoke 方法對控制項進行調用),則為 true;否則為 false。 Windows 表單中的控制項被綁定到特定的線程,不具備執行緒安全性 。因此,如果從另一個線程調用控制項的方法,那麼必須使用控制項的一個 Invoke 方法來將調用封送到適當的線程。該屬性可用於確定是否必須調用 Invoke 方法,當不知道什麼線程擁有控制項時這很有用。

下面來說下這個的用法(我的一般做法): 首先定義一個委託,與這個事件處理函數的簽名一樣委託,當然直接使用該事件的委託也是可以的,如:

private   delegate   void  InvokeCallback( string  msg);

然後就是判斷這個屬性的值來決定是否要調用Invoke函數:

 

 void  m_comm_MessageEvent( string  msg)    

{      if (txtMessage.InvokeRequired)     

   {     

    InvokeCallbackmsgCallback  =   new  InvokeCallback(m_comm_MessageEvent);     

     txtMessage.Invoke(msgCallback,  new   object []  { msg } );  

   }      

  else     

{      txtMessage.Text  =  msg;     }  

說明:這個函數就是事件處理函數,txtMessage是一個文字框。 這樣就做到了表單中控制項的執行緒安全性。

void m_comm_MessageEvent( string msg) { if (txtMessage.InvokeRequired) { InvokeCallbackmsgCallback = new InvokeCallback(m_comm_MessageEvent); txtMessage.Invoke(msgCallback, new object [] { msg } ); } else { txtMessage.Text = msg; }

 

------------------

InvokeRequired 當前線程不是建立控制項的線程時為true 比如你可以自己開一個Thread,或使用Timer的事件來訪問表單上的控制項的時候,線上程中表單的這個屬性就是True的。
簡單的說,如果有兩個線程,Thread A和Thread B,並且有一個Control c,是在Thread A裡面new的。 那麼在Thread A裡面啟動並執行任何方法調用c.InvokeRequired都會返回false。 相反,如果在Thread B裡面啟動並執行任何方法調用c.InvokeRequired都會返回true。 是否是UI線程與結果無關。(通常Control所在的線程是UI線程,但是可以有例外)
也可以認為,在new Control()的時候,control用一個變數記錄下了當前線程,在調用InvokeRequired時,返回當前線程是否不等於new的時候記錄下來的那個線程。

--------------------

我理解:如果InvokeRequired==true表示其它線程需要訪問控制項,那麼調用invoke來轉給控制項owner處理。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.