關於Invoke和InvokeRequired


在多線程應用中將會涉及不同的線程訪問同一控件的問題,C#中禁止跨線程直接訪問控件。某個控件在被創建時就記下了是誰創建了它,即它的創建線程。如果從另一個線程調用該控件,那么必須使用控件的 Invoke 方法來將調用封送現在調用它的線程。

到底是哪個線程要使用該控件呢?需要用InvokeRequired來詢問一下,如果當前調用線程不是控件的創建線程,則為 true;否則為 false。

一個典型的使用方法是:


private void ReceiveMessage()
{
IPEndPoint remoteIpEndPoint = new IPEndPoint(IPAddress.Any,0);
while (true)
{
try
{
// 關閉receiveUdpClient時此時會產生異常
byte[] receiveBytes = receiveUdpClient.Receive(ref remoteIpEndPoint);
string receivemessage = Encoding.Unicode.GetString(receiveBytes);
//顯示消息內容
ShowMessage(lstMessageBox,string.Format("{0}[{1}]",remoteIpEndPoint,receivemessage));
}
catch
{
break;
}
}
}
/// <summary>
/// // 通過委托回調機制顯示消息內容
/// </summary>
delegate void ShowMessageCallback(ListBox listbox,string text);
private void ShowMessage(ListBox listbox, string text)
{//如果控件的 Handle 是在與調用線程不同的線程上創建的(此時,您必須通過 Invoke 方法對控件進行調用),則為 true;否則為 false。
//如果從另一個線程調用控件的方法,那么必須使用控件的一個 Invoke 方法來將調用封送到適當的線程。
if (listbox.InvokeRequired)
{
ShowMessageCallback showmessagecallback = ShowMessage;
listbox.Invoke(showmessagecallback, new object[] { listbox, text });
}
else
{
listbox.Items.Add(text);
listbox.SelectedIndex = listbox.Items.Count - 1;
listbox.ClearSelected();
}
}


 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM