关于Invoke和InvokeRequired

Posted 悬崖累码

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于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的主要内容,如果未能解决你的问题,请参考以下文章

关于 Invoke、Invokerequired 和多线程的 C# 问题

Invoke 和 BeginInvoke 的区别

Winform中Control的Invoke与BeginInvoke方法

使用 P/Invoke 从 Unity 高效地与非托管代码对话

Powershell invoke-sqlcmd 打印错误的输出

invoke和beginInvoke