Cool_Breeze 发表于 2021-3-21 13:08

C# 学习笔记 线程池,线程事件锁

本帖最后由 Cool_Breeze 于 2021-3-21 14:14 编辑

using System;
using System.Threading;
using System.Collections.Concurrent;

class Program
{
    static void Main()
    {
         // 事件锁 字段 AutoReset 在事件锁被终止时,等待一个线程执行后,自动恢复,阻塞线程。
         // ManualReset 线程执行完,需要手动恢复事件锁,不然线程将不会被阻塞。
      EventWaitHandle ewh1 = new EventWaitHandle(false, EventResetMode.AutoReset);
      EventWaitHandle ewh2 = new EventWaitHandle(false, EventResetMode.AutoReset);
      EventWaitHandle ewh3 = new EventWaitHandle(false, EventResetMode.AutoReset);
      EventWaitHandle ewh4 = new EventWaitHandle(false, EventResetMode.AutoReset);
      
      QueueArgs[] queueArgs =
      {
            new QueueArgs(){ewh = ewh1},
            new QueueArgs(){ewh = ewh2},
            new QueueArgs(){ewh = ewh3},
            new QueueArgs(){ewh = ewh4},
      };
      
      // WaitCallback 委托类型 // 不太清楚线程池的工作原理
      // ThreadPool.QueueUserWorkItem(new WaitCallback(Print), queueArgs);
      // ThreadPool.QueueUserWorkItem(new WaitCallback(Print), queueArgs);
      // ThreadPool.QueueUserWorkItem(new WaitCallback(Print), queueArgs);
      // ThreadPool.QueueUserWorkItem(new WaitCallback(Print), queueArgs);
      
      Thread[] ThPool = new Thread; // 自定义线程池也有这个问题,但还好。
      for (int i=0; i<ThPool.Length; i++)
            ThPool = new Thread(new ParameterizedThreadStart(Print)); // ParameterizedThreadStart 带参数委托类型
      for (int i=0; i<ThPool.Length; i++)
            ThPool.Start(queueArgs);
      
      int Order = 20;
      for (int i=0; i<Order ;i++)
      {
            QueueArgs.queue.Enqueue(i);
      }
      
      for (int i=0; i<queueArgs.Length ;i++)
      {
            QueueArgs.queue.Enqueue(-1); // 终止线程
      }
      
      for (int n=0; n<(Order+queueArgs.Length)/queueArgs.Length ; n++)
      {
            Console.WriteLine("第 {0} 轮", n+1);
            foreach (var qA in queueArgs)
            {
                qA.ewh.Set(); // 将事件终止 线程可以继续
                Thread.Sleep(1); // 开启线程池(ThreadPool)延迟太短了,线程还没有轮到它就又锁上了,这个不好管控
                qA.ewh.Reset(); // 将事件恢复, 线程阻塞
            }
      }
    }
   
    class QueueArgs
    {
      public static readonly ConcurrentQueue<int> queue = new ConcurrentQueue<int>();
      public EventWaitHandle ewh; // 事件锁
    }
   
    static void Print(object Args) // 签名和 WaitCallback 一致
    {
      QueueArgs args = Args as QueueArgs;
      int temp;
      while (true)
      {
            args.ewh.WaitOne();
            QueueArgs.queue.TryDequeue(out temp);
            Console.WriteLine("Number {0}", temp);
            if (temp == -1) break; // 退出线程
      }
    }}

第 1 轮
Number 0
Number 1
Number 2
Number 3
第 2 轮
Number 4
Number 5
Number 6
Number 7
第 3 轮
Number 8
Number 9
Number 10
Number 11
第 4 轮
Number 12
Number 13
Number 14
Number 15
第 5 轮
Number 16
Number 17
Number 18
Number 19
第 6 轮
Number -1
Number -1
Number -1
Number -1

dxaw2458 发表于 2021-3-21 19:05

你学c#是看书还是看视频教程 ? 我也想学习下

LongYuan11 发表于 2021-3-21 19:33

事件锁终止,可以再次解锁并启动它吗?

piyaohua 发表于 2021-3-22 12:57

dxaw2458 发表于 2021-3-21 19:05
你学c#是看书还是看视频教程 ? 我也想学习下

看视频啊,书也看
页: [1]
查看完整版本: C# 学习笔记 线程池,线程事件锁