首页 > 代码库 > 关于Invoke和InvokeRequired

关于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();
}
}


 

关于Invoke和InvokeRequired