C#中禁止跨线程直接访问控件,InvokeRequired是为了解决这个问题而产生的,当一个控件的InvokeRequired属性值为真时,说明有一个创建它以外的线程想访问它。
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;
}
}
----以上为转载内容
以下是个人的另一种实现方法:
调用机制代码:
public static class FormUtils { public static void InvokeDele(this Control sender, Action<DeleArgs> action, DeleArgs args) { if (sender.InvokeRequired) { sender.Invoke(action, args); } else action(args); } } //参数类 public class DeleArgs : EventArgs { public DeleArgs(object[] args) { Args = args; } public object[] Args { get; set; } }
窗体中的调用示例:
Action<DeleArgs> action = new Action<DeleArgs>(args => { object parm1 = (object)args.Args[0]; string parm2 = (string)args.Args[1]; ... }); DeleArgs arg = new DeleArgs(new object[] { parmVal1, parmVal2 }); FormUtils.InvokeDele(this, action, arg);
方法2:
调用机制:
public static void InvokeMethod(this Control control, Delegate action, params object[] args) { if (control.InvokeRequired) control.Invoke(action, args); else action.DynamicInvoke(args); }
调用:
this.InvokeMethod(new DeleRefreshFilter(FilterFlightDatas), p.strfilter, p.isFilter, p.isFlag);