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