C#多线程之线程通讯(AutoResetEvent)

一、简介

我们在线程编程的时候往往会涉及到线程的通信,通过信号的接受来进行线程是否阻塞的操作。
AutoResetEvent 允许线程通过发信号互相通信。通常,此通信涉及线程需要独占访问的资源。具体方法和扩展方法请详见AutoResetEvent类,最常用方法中就有Set()和WaitOne()。
线程通过调用 AutoResetEvent 上的 WaitOne 来等待信号。如果 AutoResetEvent 处于非终止状态,则该线程阻塞,并等待当前控制资源的线程通过调用 Set 发出资源可用的信号。AutoResetEvent 的非终止状态可以通过构造函数在设置。
通俗的来讲只有等myResetEven.Set()成功运行后,myResetEven.WaitOne()才能够获得运行机会;Set是发信号,WaitOne是等待信号,只有发了信号,
等待的才会执行。如果不发的话,WaitOne后面的程序就永远不会执行。

AutoResetEvent myEvent = new AutoResetEvent(false);

这里构造函数中的参数false就代表该状态为非终止状态,相反若为true则为终止状态。

二、代码

案例一:

    public class Program
    {
        const int cycleNum = 10;static void Main(string[] args)
        {
            // 参数:
            // workerThreads:
            // 要由线程池根据需要创建的新的最小工作程序线程数。
            // completionPortThreads:
            // 要由线程池根据需要创建的新的最小空闲异步 I/O 线程数。
            // 返回结果:如果更改成功,则为 true;否则为 false。
            //public static bool SetMinThreads(int workerThreads, int completionPortThreads);
            ThreadPool.SetMinThreads(1, 1);
            // 参数:
            // workerThreads:
            // 线程池中辅助线程的最大数目。
            // completionPortThreads:
            // 线程池中异步 I/O 线程的最大数目。
            // 返回结果:如果更改成功,则为 true;否则为 false。
            //public static bool SetMaxThreads(int workerThreads, int completionPortThreads);
            ThreadPool.SetMaxThreads(5, 5);
            for (int i = 1; i <= cycleNum; i++)
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(testFun), i.ToString());
            }
            Console.WriteLine("主線程執行!");
            Console.WriteLine("主線程終止!");
            Console.WriteLine("線程池終止!");
            Console.ReadKey();
        }
        public static void testFun(object obj)
        {
            Console.WriteLine(string.Format("{0}:第{1}個線程", DateTime.Now.ToString(), obj.ToString()));
            Thread.Sleep(5000);
        }
    }

运行结果:

这里可以看出,线程池里线程的执行不影响主线程的运行,线程池虽然可以管理多线程的执行,但是却无法知道它什么时候终止。

案例二:

    public class Program
    {
        const int cycleNum = 10;
        static int cnt = 10;
        static AutoResetEvent myEvent = new AutoResetEvent(false);
        static void Main(string[] args)
        {
            // 参数:
            // workerThreads:
            // 要由线程池根据需要创建的新的最小工作程序线程数。
            // completionPortThreads:
            // 要由线程池根据需要创建的新的最小空闲异步 I/O 线程数。
            // 返回结果:如果更改成功,则为 true;否则为 false。
            //public static bool SetMinThreads(int workerThreads, int completionPortThreads);
            ThreadPool.SetMinThreads(1, 1);
            // 参数:
            // workerThreads:
            // 线程池中辅助线程的最大数目。
            // completionPortThreads:
            // 线程池中异步 I/O 线程的最大数目。
            // 返回结果:如果更改成功,则为 true;否则为 false。
            //public static bool SetMaxThreads(int workerThreads, int completionPortThreads);
            ThreadPool.SetMaxThreads(5, 5);
            for (int i = 1; i <= cycleNum; i++)
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(testFun), i.ToString());
            }
            Console.WriteLine("主線程執行!");
            Console.WriteLine("主線程終止!");
            myEvent.WaitOne();
            Console.WriteLine("線程池終止!");
            Console.ReadKey();
        }
        public static void testFun(object obj)
        {
            cnt -= 1;//信號量自減
            Console.WriteLine(string.Format("{0}:第{1}個線程", DateTime.Now.ToString(), obj.ToString()));
            Thread.Sleep(5000);
            if (cnt == 0)
            {
                myEvent.Set();
            }
        }
    }

运行结果:

上面例子中一开始非终止状态,当遇到WaitOne()方法时则会阻塞线程,在没有set()时将一直处于阻塞状态.

三、总结

既然说到了AutoResetEvent,就不得不说ManualResetEvent,这两个方法几乎相同,不同的地方就在于AutoResetEvent的WaitOne()方法执行后会自动又将信号置为不发送状态也就是阻塞状态,当再次遇到WaitOne()方法是又会被阻塞,而ManualResetEvent则不会,只要线程处于非阻塞状态则无论遇到多少次WaitOne()方法都不会被阻塞,除非调用ReSet()方法来手动阻塞线程。

到此这篇关于C#多线程之线程通讯(AutoResetEvent)的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C#多线程中的互斥锁Mutex

    一.简介 Mutex的突出特点是可以跨应用程序域边界对资源进行独占访问,即可以用于同步不同进程中的线程,这种功能当然这是以牺牲更多的系统资源为代价的. 主要常用的两个方法: public virtual bool WaitOne() 阻止当前线程,直到当前 System.Threading.WaitHandle 收到信号获取互斥锁. public void ReleaseMutex() 释放 System.Threading.Mutex 一次. 二.代码 案例一: class Program {

  • C#多线程之线程池(ThreadPool)

    一.简介 前面介绍了平时用到的大多数的多线程的例子,但在实际开发中使用的线程往往是大量的和更为复杂的,这时,每次都创建线程.启动线程.从性能上来讲,这样做并不理想(因为每使用一个线程就要创建一个,需要占用系统开销):从操作上来讲,每次都要启动,比较麻烦.为此引入的线程池的概念. 好处: 1.减少在创建和销毁线程上所花的时间以及系统资源的开销 2.如不使用线程池,有可能造成系统创建大量线程而导致消耗完系统内存以及”过度切换”. 在什么情况下使用线程池? 1.单个任务处理的时间比较短 2.需要处理的

  • C#多线程的Join()方法

    一.简介 Join方法主要是用来阻塞调用线程,直到某个线程终止或经过了指定时间为止.官方的解释比较乏味,通俗的说就是创建一个子线程,给它加了这个方法,其它线程就会暂停执行,直到这个线程执行完为止才去执行(包括主线程). 二.代码 class Program { static void Main(string[] args) { Thread threadA = new Thread(ThreadMethod); threadA.Name = "線程A"; Thread threadB

  • C#使用Monitor类实现线程同步

    一.简介 Lock关键字是Monitor的一种替换用法,lock在IL代码中会被翻译成Monitor. lock (obj) { //代码段 } //就等同于 Monitor.Enter(obj); //代码段 Monitor.Exit(obj); Monitor的常用属性和方法: Enter(Object) 在指定对象上获取排他锁. Exit(Object) 释放指定对象上的排他锁. Pulse 通知等待队列中的线程锁定对象状态的更改. PulseAll 通知所有的等待线程对象状态的更改. T

  • C#多线程之线程中止Abort()方法

    一.简介 Abort()方法用来终止线程,调用此方法强制停止正在执行的线程,它会抛出一个ThreadAbortException异常从而导致目标线程的终止. 二.代码 class Program { static void Main(string[] args) { Thread thread = new Thread(ThreadMethod); //执行的必须是无返回值的方法 thread.Name = "子線程A"; thread.Start(); Console.ReadKey

  • C#使用ThreadPriority设置线程优先级

    一.简介 如果在应用程序中有多个线程在运行,但一些线程比另一些线程重要,这种情况下可以在一个进程中为不同的线程指定不同的优先级.线程的优先级可以通过Thread类Priority属性设置,Priority属性是一个ThreadPriority型枚举,列举了5个优先等级:AboveNormal.BelowNormal.Highest.Lowest.Normal.公共语言运行库默认是Normal类型的. 二.代码 class Program { static void Main(string[] a

  • C#多线程的ResetAbort()方法

    一.简介 Abort方法可以通过跑出ThreadAbortException异常中止线程,而使用ResetAbort方法可以取消中止线程的操作,下面通过代码演示使用 ResetAbort方法. 二.代码 class Program { static void Main(string[] args) { Thread thread = new Thread(ThreadMethod); //执行的必须是无返回值的方法 thread.Name = "子線程A"; thread.Start(

  • C#使用LOCK实现线程同步

    一.简介 线程安全概念:线程安全是指在当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用.不会出现数据不一致或者数据污染. 线程有可能和其他线程共享一些资源,比如,内存,文件,数据库等.当多个线程同时读写同一份共享资源的时候,可能会引起冲突.这时候,我们需要引入线程“同步”机制,即各位线程之间要有个先来后到,不能一窝蜂挤上去抢作一团.线程同步的真实意思和字面意思恰好相反.线程同步的真实意思,其实是“排队”:几个线程之间要排队,一个一个对共享资源进行操

  • C# 如何获取当前进程或线程的ID

    目录 获取当前进程或线程的ID C# 进程读取方法 获取当前进程或线程的ID 如果获得当前进程的Id用: Process[] processes = Process.GetProcesses();  foreach(Process process in processes)  {  if(process.ProcessName == "进程名"  {  MessageBox.Show(process.Id);  }  } Process processes   =Process.Get

  • C#多线程之线程通讯(AutoResetEvent)

    一.简介 我们在线程编程的时候往往会涉及到线程的通信,通过信号的接受来进行线程是否阻塞的操作.AutoResetEvent 允许线程通过发信号互相通信.通常,此通信涉及线程需要独占访问的资源.具体方法和扩展方法请详见AutoResetEvent类,最常用方法中就有Set()和WaitOne().线程通过调用 AutoResetEvent 上的 WaitOne 来等待信号.如果 AutoResetEvent 处于非终止状态,则该线程阻塞,并等待当前控制资源的线程通过调用 Set 发出资源可用的信号

  • C#多线程之线程同步WaitHandle

    一.引言 在前面的文章中,我们是使用“锁”的方式实现了线程间的通信,这种通信方式比较笨重.除了锁之外,.NET中还提供了一些线程间更自由通讯的工具,他们提供了通过“信号”进行通讯的机制,通俗的比喻为“开门”.“关门”:Set()开门.Reset()关门.WaitOne()等着. 二.WaitHandle WaitHandle位于System.Threading命名空间下,是用来封装等待对共享资源进行独占访问的操作系统特定的对象.WaitHandle是一个抽象类,我们一般不直接使用,而是使用它的派

  • C#多线程之线程锁

    目录 一.Mutex类 二.Mutex的用途 三.Semaphore信号量 1.简介 2.初始化 3.WaitOne()和Release() 四.Monitor类 典型的生产者与消费者实例 五.Lock 六.InterLocked(相当于lock,对整数) 1.Interlocked类主要方法 2.实例 一.Mutex类 “mutex”是术语“互相排斥(mutually exclusive)”的简写形式,也就是互斥量.互斥量跟临界区中提到的Monitor很相似,只有拥有互斥对象的线程才具有访问资

  • C#多线程之线程池ThreadPool详解

    一.ThreadPool概述 提供一个线程池,该线程池可用于执行任务.发送工作项.处理异步 I/O.代表其他线程等待以及处理计时器. 创建线程需要时间.如果有不同的小任务要完成,就可以事先创建许多线程/在应完成这些任务时发出请求.不需要自己创建这样一个列表.该列表由ThreadPool类托管. 这个类会在需要时增减池中线程的线程数,直到最大的线程数.池中的最大线程数是可配置的.在双核CPU中,默认设置为1023 个工作线程和1000个I/O线程.也可以指定在创建线程池时应立即启动的最小线程数,以

  • Java多线程之线程通信生产者消费者模式及等待唤醒机制代码详解

    前言 前面的例子都是多个线程在做相同的操作,比如4个线程都对共享数据做tickets–操作.大多情况下,程序中需要不同的线程做不同的事,比如一个线程对共享变量做tickets++操作,另一个线程对共享变量做tickets–操作,这就是大名鼎鼎的生产者和消费者模式. 正文 一,生产者-消费者模式也是多线程 生产者和消费者模式也是多线程的范例.所以其编程需要遵循多线程的规矩. 首先,既然是多线程,就必然要使用同步.上回说到,synchronized关键字在修饰函数的时候,使用的是"this"

  • C#多线程之线程控制详解

    本文为大家分享了C#多线程之线程控制,供大家参考,具体内容如下 方案一: 调用线程控制方法.启动:Thread.Start();停止:Thread.Abort();暂停:Thread.Suspend();继续:Thread.Resume(); private void btn_Start_Click(object sender, EventArgs e) { mThread.Start(); // 开始 } private void btn_Stop_Click(object sender, E

  • 学习Java多线程之线程定义、状态和属性

    一 .线程和进程 1. 什么是线程和进程的区别: 线程是指程序在执行过程中,能够执行程序代码的一个执行单元.在java语言中,线程有四种状态:运行 .就绪.挂起和结束. 进程是指一段正在执行的程序.而线程有事也被成为轻量级的进程,他得程序执行的最小单元,一个进程可以拥有多个线程,各个线程之间共享程序的内功空间(代码段.数据段和堆空间)及一些进程级的资源(例如打开的文件),但是各个线程都拥有自己的棧空间. 2. 为何要使用多进程 在操作系统级别上来看主要有以下几个方面: - 使用多线程可以减少程序

  • 深入理解JAVA多线程之线程间的通信方式

    一,介绍 本总结我对于JAVA多线程中线程之间的通信方式的理解,主要以代码结合文字的方式来讨论线程间的通信,故摘抄了书中的一些示例代码. 二,线程间的通信方式 ①同步 这里讲的同步是指多个线程通过synchronized关键字这种方式来实现线程间的通信. 参考示例: public class MyObject { synchronized public void methodA() { //do something.... } synchronized public void methodB()

  • Java多线程中线程间的通信实例详解

    Java多线程中线程间的通信 一.使用while方式来实现线程之间的通信 package com.ietree.multithread.sync; import java.util.ArrayList; import java.util.List; public class MyList { private volatile static List list = new ArrayList(); public void add() { list.add("apple"); } publ

  • java多线程之线程同步七种方式代码示例

    为何要使用同步?  java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数据的增删改查),     将会导致数据不准确,相互之间产生冲突,因此加入同步锁以避免在该线程没有完成操作之前,被其他线程的调用,     从而保证了该变量的唯一性和准确性. 1.同步方法  即有synchronized关键字修饰的方法.     由于java的每个对象都有一个内置锁,当用此关键字修饰方法时,     内置锁会保护整个方法.在调用该方法前,需要获得内置锁,否则就处于阻塞状态.     代码

随机推荐