C#中关于InvokeRequired 属性 与Invoke方法

原文链接:https://blog.csdn.net/Pei_hua100/article/details/107353455

 

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

 控件的InvokeRequired属性:bool值,为true时表示调用Send方法的是另一个线程,此时需要将Send方法传送给一个委托让委托所在的线程来代替执行Send方法;为false时表示Send的调用者没有跨线程调用Send方法,此时直接执行else中的代码即可。

 

posted @ 2025-10-11 15:05  yinghualeihenmei  阅读(12)  评论(0)    收藏  举报