zoukankan      html  css  js  c++  java
  • 认识ManualResetEvent

    ManualResetEvent可以通知一个或多个正在等待的线程已发生事件,允许线程通过发信号互相通信,来控制线程是否可以访问资源。 当一个线程开始一个活动(此活动必须完成后,其他线程才能开始执行)时,它调用Reset将ManualResetEvent置于非终止状态。此线程可被视为控制ManualResetEvent。 调用ManualResetEvent上的WaitOne的线程将被阻止,并等待信号。当主控线程完成活动时,它调用Set以发出等待线程可以继续进行的信号,并释放所有等待线程。 一旦它被终止,ManualResetEvent将保持终止状态,直到它被手动重置,即对WaitOne的调用将立即返回。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace ManualResetEventDemo
    {
        class Program
        {
            static void Main(string[] args)
            {
                MyThread myth = new MyThread();
                while (true)
                {
                    Console.WriteLine("输入 stop 后台线程挂起 start 后台线程开始执行!");
                    string cmd = Console.ReadLine();
                    if (cmd.ToLower().Trim() == "stop")
                    {
                        Console.WriteLine("后台线程停止运行...");
                        myth.Stop();
                    }
                    else if (cmd.ToLower().Trim() == "start")
                    {
                        Console.WriteLine("后台线程开始执行...");
                        myth.Start();
                    }
                }
            }
        }
    
        /// <summary>
        ///         | 调用Set被控线程可执行      |
        ///         |------------------------>|
        ///         |                         |
        /// 主控线程 |---->ManualResetEvent--->|被控线程
        ///         |        控制信号          |
        ///         |                         |  
        ///         |------------------------>|
        ///         |调用Reset被控线程停止运行    |
        /// </summary>
        class MyThread
        {
            Thread t = null;
            // ManualResetEvent允许线程通过发信号互相通信。通常,此通信涉及一个线程在其他线程进行之前必须完成的任务。
            // 通过将布尔值传递给构造函数来控制ManualResetEvent的初始状态,如果初始状态处于终止状态,为true,否则为false。
            ManualResetEvent manualEvent = new ManualResetEvent(false); // 为true,一开始就可以执行,为false,后台线程处于阻塞态。
            private void Run()
            {
                while (true)
                {
                    // 调用ManualResetEvent上的WaitOne方法的线程,称为被控线程。
                    // 当主控线程调用ManualResetEvent上的Set方法,发出等待线程可以继续进行的信号,并释放所有等待线程,被控线程可执行。此时ManualResetEvent处于终止状态
                    // 当主控线程调用ManualResetEvent上的Reset方法,被控线程将阻塞,并等待信号。此时ManualResetEvent处于非终止状态。
                    manualEvent.WaitOne();
                    Console.WriteLine("线程id:{0}",Thread.CurrentThread.ManagedThreadId);
                    Thread.Sleep(200);
                }
            }
            public void Start()
            {
                manualEvent.Set();
            }
            public void Stop()
            {
                manualEvent.Reset();
            }
            public MyThread()
            {
                t = new Thread(Run);
                t.IsBackground = true;
                t.Start();
            }
        }
    }
    

      

  • 相关阅读:
    Bitmap\Bytes\BitmapImage相互转换
    枚举值为什么使用1,2,4,8,16,32等2的幂方(转)
    获取电脑信息
    操作内存的帮助类
    C#调用DLL(整理)
    [原]java集合类TreeMap和TreeSet
    [原]《面试题精选》08.颠倒句子中单词的顺序
    [原]数据结构与对象的区别
    [原]初步了解Hadoop平台
    [原]《程序员面试题精选》06.查找最小的k个元素
  • 原文地址:https://www.cnblogs.com/youknowUL/p/11331560.html
Copyright © 2011-2022 走看看