c#多线程通信之委托事件

 更新时间:2021年04月07日 16:45:51   作者:richerg85  
这篇文章主要介绍了c#多线程通信之委托事件,对多线程感兴趣的同学可以参考下

在研究c# 线程之间通信时,发现传统的方法大概有三种:

  1. 全局变量,由于同一进程下的多个进程之间共享数据空间,所以使用全局变量是最简单的方法,但要记住使用volatile进行限制。
  2. 线程之间发送消息(这个随后文章中会讨论到)。
  3.  CEvent为MFC中的一个对象,可以通过对CEvent的触发状态进行改变,从而实现线程间的通信和同步,这个主要是实现线程直接同步的一种方法。

本文介绍的一种方法是这三种之外的一种方法,本文中实例是通过创建一个线程类,通过委托事件把值传送到Form所在的类中,同时更新Form类中的一个控件(Label)中的值。

实现功能比较简单,目的是实现此功能,先把代码贴上:

MyThread.cs

using System;
using System.Threading;
 
namespace ThreadsComm
{
 public delegate void ReadParamEventHandler(string sParam);
 class MyThread
 {
  public Thread thread1;
  private static ReadParamEventHandler OnReadParamEvent;
  public MyThread()
  {
   thread1 = new Thread(new ThreadStart(MyRead));
   thread1.IsBackground = true;
   thread1.Start();
  }
  public event ReadParamEventHandler ReadParam
  {
   add { OnReadParamEvent += new ReadParamEventHandler(value);}
   remove{ OnReadParamEvent -= new ReadParamEventHandler(value);}
  }
  protected void MyRead()
  {
   int i = 0;
   while (true)
   {
    Thread.Sleep(1000);
    i = i + 1;
    OnReadParamEvent(i.ToString());//触发事件
   }
  }
 }
}

其中的

public event ReadParamEventHandler ReadParam
  {
   add { OnReadParamEvent += new ReadParamEventHandler(value);}
   remove{ OnReadParamEvent -= new ReadParamEventHandler(value);}
  }

这个需要说明一下:

add 上下文关键字用于定义一个自定义事件访问器,当客户端代码订阅您的事件时将调用该访问器。 如果提供自定义 add 访问器,还必须提供 remove 访问器。

remove 上下文关键字用于定义一个自定义事件访问器,当客户端代码取消订阅事件时将调用该访问器。 如果提供自定义 remove 访问器,还必须提供 add 访问器。
Form.cs

using System;
using System.Windows.Forms;
 
namespace ThreadsComm
{
 public partial class Form1 : Form
 {
  private static string param = "";
  public Form1()
  {
   InitializeComponent();
   MyThread thread1 = new MyThread();
   thread1.ReadParam += this.OnRead;
  }
 
  private void OnRead(string sParam)
  {
   param = sParam;
   Object[] list = { this,System.EventArgs.Empty};
   this.lblShow.BeginInvoke(new EventHandler(LabelShow), list);
  }
  protected void LabelShow(Object o, EventArgs e)
  {
   this.lblShow.Text = param;
  }
 }
}

其中的

 MyThread thread1 = new MyThread();
 thread1.ReadParam += this.OnRead;

是订阅线程类中的事件。

 this.lblShow.BeginInvoke(new EventHandler(LabelShow), list);

Invoke或者 BeginInvoke方法都需要一个委托对象作为参数。委托类似于回调函数的地址,因此调用者通过这两个方法就可以把需要调用的函数地址封送给界面线程。这些方法里面如果包含了更改控件状态的代码,那么由于最终执行这个方法的是界面线程,从而避免了竞争条件,避免了不可预料的问题。如果其它线程直接操作界面线程所属的控件,那么将会产生竞争条件,造成不可预料的结果。

使用 Invoke完成一个委托方法的封送,就类似于使用 SendMessage方法来给界面线程发送消息,是一个同步方法。也就是说在 Invoke封送的方法被执行完毕前, Invoke方法不会返回,从而调用者线程将被阻塞。

使用 BeginInvoke方法封送一个委托方法,类似于使用 PostMessage进行通信,这是一个异步方法。也就是该方法封送完毕后马上返回,不会等待委托方法的执行结束,调用者线程将不会被阻塞。但是调用者也可以使用 EndInvoke方法或者其它类似 WaitHandle机制等待异步操作的完成。

但是在内部实现上, Invoke和 BeginInvoke都是用了 PostMessage方法,从而避免了 SendMessage带来的问题。而 Invoke方法的同步阻塞是靠 WaitHandle机制来完成的。

想实验的读者可以建一个winform工程,采用上边的代码试验一下。

以上就是c#多线程通信之委托事件的详细内容,更多关于c#多线程委托事件的资料请关注脚本之家其它相关文章!

相关文章

  • C# 获取数据库中所有表名、列名的示例代码

    C# 获取数据库中所有表名、列名的示例代码

    这篇文章主要介绍了C# 获取数据库中所有表名、列名,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • C#中Mutex对象用法分析

    C#中Mutex对象用法分析

    这篇文章主要介绍了C#中Mutex对象用法,结合实例形式分析了Mutex对象的功能与线程操作的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2016-06-06
  • C#中的反射(System.Reflection)

    C#中的反射(System.Reflection)

    这篇文章介绍了C#中的反射(System.Reflection),文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-05-05
  • WPF InkCanvas基本操作方法详解

    WPF InkCanvas基本操作方法详解

    这篇文章主要为大家详细介绍了WPF InkCanvas基本的操作方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-11-11
  • C#统计字符串里中文汉字个数的方法

    C#统计字符串里中文汉字个数的方法

    这篇文章主要介绍了C#统计字符串里中文汉字个数的方法,本文通过正则实现统计出一段字符串里中文字数,需要的朋友可以参考下
    2014-08-08
  • C#多线程中的互斥锁Mutex

    C#多线程中的互斥锁Mutex

    这篇文章介绍了C#多线程中的互斥锁Mutex,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-04-04
  • Winform中GridView分组排序功能实现方法

    Winform中GridView分组排序功能实现方法

    这篇文章主要介绍了Winform中GridView分组排序功能实现方法,以实例形式详细说明了分组排序的实现方法,并附带完整的DBHelp类代码,是非常实用的技巧,需要的朋友可以参考下
    2014-11-11
  • C#编程获取IP地址的方法示例

    C#编程获取IP地址的方法示例

    这篇文章主要介绍了C#编程获取IP地址的方法,结合实例形式分析了C#获取客户端IP地址的具体实现技巧,需要的朋友可以参考下
    2017-01-01
  • C#如何生成唯一订单号

    C#如何生成唯一订单号

    这篇文章主要为大家详细介绍了C#如何生成唯一订单号,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-08-08
  • Oracle中for循环的使用方法

    Oracle中for循环的使用方法

    这篇文章介绍了Oracle中for循环的使用方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-08-08

最新评论