1. Invoke and BeginInvoke

   control.invoke(参数delegate)方法:在拥有此控件的基础窗口句柄的线程上执行指定的委托。

      control.begininvoke(参数delegate)方法:在创建控件的基础句柄所在线程上异步执行指定委托。

        使用Invoke完成一个委托方法的封送,就类似于使用SendMessage方法来给界面线程发送消息,是一个同步方法。

     使用BeginInvoke方法封送一个委托方法,类似于使用PostMessage进行通信,这是一个异步方法。

  .net freamwork3.5 之后 可以用action封装匿名方法。 

  this.Invoke(new Action()=>

  {

    要执行的代码;

  });

2. SynchronizationContext

  SynchronizationContext在通讯中充当传输者的角色,实现功能就是一个线程和另外一个线程的通讯。

 

  Send() 是简单的在当前线程上去调用委托来实现(同步调用)。也就是在子线程上直接调用UI线程执行,等UI线程执行完成后子线程才继续执行。
     Post() 是在线程池上去调用委托来实现(异步调用)。这是子线程会从线程池中找一个线程去调UI线程,子线程不等待UI线程的完成而直接执行自己下面的代码。

  例子:

  private SynchronizationContext mainThreadSynContext;

  

  

  public UdpServer(int port)
  {
    udpServer = new UdpClient(port);
    ipEndPoint = new IPEndPoint(IPAddress.Any, port);
    udpServer.Client.Blocking = false;//设置为非阻塞模式
    mainThreadSynContext = SynchronizationContext.Current;//在这里记录主线程的上下文

    /// 网络数据接收线程
    Thread th = new Thread(Receive);
    // th.IsBackground = true;
    th.IsBackground = true;
    th.Start();
  }

  

  void Receive()
  {
    byte[] recBuffer;
    //远端IP
    IPEndPoint remotePoint = new IPEndPoint(IPAddress.Any, 0);
    while (true)
    {
      try
      {
        recBuffer = udpServer.Receive(ref remotePoint);
        if (recBuffer != null)
        {
        int dataLength = recBuffer[4] * 256 + recBuffer[5];
        if (recBuffer.Length == 24)
        {
        HeartBeat heartBeat = getYFRadar.GetHeart(recBuffer);
        mainThreadSynContext.Post(new SendOrPostCallback(GetRadarAz), heartBeat.ToString());

        // Form1.form1.DrawFixJammerDirctGD(heartBeat);
        }

      }
    }
  }
    catch (Exception e)
  {
    string.Format(e.ToString());
  }
  

  public void GetRadarAz(object o)
  {
    double az = Convert.ToDouble(o.ToString());
    Form1.form1.DrawFixJammerDirctGD(az);
  }

 posted on 2019-10-11 14:25  风雪逆旅  阅读(574)  评论(0编辑  收藏  举报