C#多线程系列之手动线程通知

 更新时间:2022年02月13日 15:46:33   作者:痴者工良  
本文详细讲解了C#多线程中的手动线程通知,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

区别与示例

AutoResetEvent 和 ManualResetEvent 十分相似。两者之间的区别,在于前者是自动(Auto),后者是手动(Manua)。

你可以先运行下面的示例,再测试两者的区别。

AutoResetEvent 示例:

    class Program
    {
        // 线程通知
        private static AutoResetEvent resetEvent = new AutoResetEvent(false);

        static void Main(string[] args)
        {
            // 创建线程
            new Thread(DoOne).Start();

            // 用于不断向另一个线程发送信号
            while (true)
            {
                Console.ReadKey();
                resetEvent.Set();           // 发生通知,设置终止状态
            }
        }

        public static void DoOne()
        {
            Console.WriteLine("① 等待中,请发出信号允许我运行");
            resetEvent.WaitOne();

            Console.WriteLine("② 等待中,请发出信号允许我运行");

            resetEvent.WaitOne();
            Console.WriteLine("③ 等待中,请发出信号允许我运行");
            
            // ...

            Console.WriteLine("线程结束");
        }
    }

ManualResetEvent 类示例:

    class Program
    {
        private static ManualResetEvent resetEvent = new ManualResetEvent(false);
        static void Main(string[] args)
        {
            new Thread(DoOne).Start();
            // 用于不断向另一个线程发送信号
            while (true)
            {
                Console.ReadKey();
                resetEvent.Set();           // 发生通知,设置终止状态
            }
        }

        public static void DoOne()
        {
            Console.WriteLine("等待中,请发出信号允许我运行");
            resetEvent.WaitOne();

            // 后面的都无效,线程会直接跳过而无需等待
            resetEvent.WaitOne();
            resetEvent.WaitOne();
            resetEvent.WaitOne();
            resetEvent.WaitOne();
            resetEvent.WaitOne();
            Console.WriteLine("线程结束");
        }
    }

因为 AutoResetEvent 对象在 .WaitOne() 方法等待信号完毕后,会自动重置为非终止状态,相当于高速收费站自动闸门,一辆车过去后,机器自动关闸。

ManualResetEvent 相当于人工闸门,打开后编写人工关闭闸门,不然的话闸门会一直处于打开状态。

ManualResetEvent 主要用于更加灵活的线程信号传递场景。

ManualResetEvent 类

表示线程同步事件,收到信号时,要想下一次依然生效,必须手动重置该事件。

因为 ManualResetEvent 类跟 AutoManualResetEvent 类十分接近,这里就不赘述了。

它们的使用区别主要是:

AutoResetEvent 类,每次 Set() ,跳过一个 WaitOne()。因为会 自动恢复设置,所以下次碰到 WaitOne() 会继续等待。

ManualResetEvent 类, Set() 后,不会重置设置,因此一旦使用了 Set() 后,就会一路放通,不会再等待。

其构造函数如下:

构造函数说明
ManualResetEvent(Boolean)用一个指示是否将初始状态设置为终止的布尔值初始化 ManualResetEvent 类的新实例。

其常用方法如下:

方法说明
Close()释放由当前 WaitHandle 占用的所有资源。
Reset()将事件状态设置为非终止,从而导致线程受阻。
Set()将事件状态设置为有信号,从而允许一个或多个等待线程继续执行。
WaitOne()阻止当前线程,直到当前 WaitHandle 收到信号。
WaitOne(Int32)阻止当前线程,直到当前 WaitHandle 收到信号,同时使用 32 位带符号整数指定时间间隔(以毫秒为单位)。
WaitOne(Int32, Boolean)阻止当前线程,直到当前的 WaitHandle 收到信号为止,同时使用 32 位带符号整数指定时间间隔,并指定是否在等待之前退出同步域。
WaitOne(TimeSpan)阻止当前线程,直到当前实例收到信号,同时使用 TimeSpan 指定时间间隔。
WaitOne(TimeSpan, Boolean)阻止当前线程,直到当前实例收到信号为止,同时使用 TimeSpan 指定时间间隔,并指定是否在等待之前退出同步域。

ManualResetEventSlim

ManualResetEventSlim 相对 ManualResetEvent ,当等待时间预计非常短并且事件不跨越进程边界时,可以使用此类来获得比 ManualResetEvent 更好的性能。

从代码使用来看,没有啥区别,主要就是考虑性能下时,两者不同场景。

这里就不对这两个类型赘述了。

到此这篇关于C#多线程系列之手动线程通知的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • C# 遍历datatable字段名和value的案例

    C# 遍历datatable字段名和value的案例

    这篇文章主要介绍了C# 遍历datatable字段名和value的案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • C# wpf使用ffmpeg命令行实现录屏的示例代码

    C# wpf使用ffmpeg命令行实现录屏的示例代码

    本文主要介绍了C# wpf使用ffmpeg命令行实现录屏的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • 优雅又实用的C#代码优化技巧分享

    优雅又实用的C#代码优化技巧分享

    这篇文章主要为大家整理了一些优雅又实用的C#代码优化技巧,文中的示例代码讲解详细,对我们深入了解C#有一定的帮助,需要的可以参考一下
    2023-06-06
  • c#构造初始化的顺序浅析

    c#构造初始化的顺序浅析

    这篇文章介绍了c#构造初始化的顺序,有需要的朋友可以参考一下
    2013-08-08
  • 浅谈C#中的Infinity和NaN

    浅谈C#中的Infinity和NaN

    下面小编就为大家带来一篇浅谈C#中的Infinity和NaN。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • C#使用FileInfo和DirectoryInfo类来执行文件和文件夹操作

    C#使用FileInfo和DirectoryInfo类来执行文件和文件夹操作

    System.IO.FileInfo 和 System.IO.DirectoryInfo 是C#中用于操作文件和文件夹的类,它们提供了许多有用的方法和属性来管理文件和文件夹,这篇文章主要介绍了C#使用FileInfo和DirectoryInfo类来执行文件和文件夹操作,需要的朋友可以参考下
    2023-08-08
  • c#对象初始化顺序实例分析

    c#对象初始化顺序实例分析

    这篇文章主要介绍了c#对象初始化顺序,实例分析了C#对象初始化的相关使用技巧与调用顺序,需要的朋友可以参考下
    2015-06-06
  • C# 枚举的使用简介

    C# 枚举的使用简介

    这篇文章主要介绍了C# 枚举的简单使用,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下
    2021-03-03
  • 详解c# SpinWait

    详解c# SpinWait

    这篇文章主要介绍了c# SpinWait的相关资料,帮助大家更好的理解和学习c# 编程,感兴趣的朋友可以了解下
    2020-10-10
  • C#实现从PDF中提取表格的方法详解

    C#实现从PDF中提取表格的方法详解

    PDF是办公中比较常见的一种文件格式,在工作中应用也越来越普遍。今天为大家介绍一种通过C#/VB.NET代码从PDF中提取表格内容的方法,感兴趣的可以动手尝试一下
    2022-08-08

最新评论