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);