zoukankan      html  css  js  c++  java
  • C#线程从陌生到熟悉(3)

    今天我们来谈谈线程池:

    应用程序可以有多个线程,这些线程在休眠状态中需要耗费大量时间来等待事件发生。其他线程可能进入睡眠状态,并且仅定期被唤醒以轮循更改或更新状态信息,然后再次进入休眠状态。为了简化对这些线程的管理,.NET框架为每个进程提供了一个线程池,一个线程池有若干个等待操作状态,当一个等待操作完成时,线程池中的辅助线程会执行回调函数。线程池中的线程由系统管理,程序员不需要费力于线程管理,可以集中精力处理应用程序任务。通过基础类库中的ThreadPool类提供一个线程池,该线程池可用于发送工作现,处理异步I/O,代表其他线程等待及处理计时器.ThreadPool类的所有方法都是静态方法.ThreadPool本身也是一个静态类.
    我们来看看他的定义和一些常用的方法:
     public static class ThreadPool
    {
     [SecuritySafeCritical]
            public static void GetAvailableThreads(out int workerThreads, out int completionPortThreads);
            [SecuritySafeCritical]
            public static void GetMaxThreads(out int workerThreads, out int completionPortThreads);
            [SecuritySafeCritical]
            public static void GetMinThreads(out int workerThreads, out int completionPortThreads);
            [SecuritySafeCritical]
            public static bool QueueUserWorkItem(WaitCallback callBack);
            [SecuritySafeCritical]
            public static bool QueueUserWorkItem(WaitCallback callBack, object state);
    }
    GetAvailableThreads这个方法返回的最大线程池线程数和当前活动线程数之间的差值。 参数 workerThreads: 可用辅助线程的数目。completionPortThreads: 可用异步 I/O 线程的数目。
    GetMaxThreads方法获得当前由线程池维护的辅助线程的最大数目.参数 workerThreads: 线程池中辅助线程的最大数目。completionPortThreads: 当前由线程池维护的空闲异步 I/O 线程的最大数目。
    GetMinThreads方法获得当前由线程池维护的空闲辅助线程的最小数目.参数 workerThreads: 当前由线程池维护的空闲辅助线程的最小数目.completionPortThreads: 当前由线程池维护的空闲异步 I/O 线程的最小数目。
    QueueUserWorkItem方法将方法排入队列以便执行。参数callBack, 表示要执行的方法.state:包含方法所用数据的对象。
    下面看个例子:

     1 using System;
    2 using System.Collections.Generic;
    3 using System.Linq;
    4 using System.Text;
    5 using System.Threading;
    6
    7 namespace ConsoleApplication6
    8 {
    9 class Program
    10 {
    11 static void Main(string[] args)
    12 {
    13 Console.WriteLine("主线程进行异步条用");
    14
    15 AutoResetEvent asyncOpIsDone = new AutoResetEvent(false);
    16 ThreadPool.QueueUserWorkItem(new WaitCallback((x) =>
    17 {
    18
    19 Thread.Sleep(1000);
    20 Console.WriteLine("工作任务");
    21
    22 }));
    23 string s="我的参数";
    24 ThreadPool.QueueUserWorkItem(new WaitCallback((x) =>
    25 {
    26
    27 Thread.Sleep(2000);
    28 Console.WriteLine("工作任务1");
    29 Console.WriteLine(x);
    30
    31 }), s);
    32 ThreadPool.QueueUserWorkItem(new WaitCallback(MyAsyncOperation), asyncOpIsDone);
    33 Console.WriteLine("主线程执行其他");
    34 Console.WriteLine("主线程等待任务处理结束");
    35 asyncOpIsDone.WaitOne();
    36 }
    37 static void MyAsyncOperation(Object state)
    38 {
    39
    40 Thread.Sleep(5000);
    41 Console.WriteLine("工作任务2");
    42 ((AutoResetEvent)state).Set();
    43 }
    44 }
    45 }

     运行的结果为

    这里有个类为AutoResetEvent,他的作用是通知正在等待的线程已发生事件。他是从EventWaitHandle继承而来的!例子中分别用了两种不同的方式调用,第二种是可以传递参数的!工作线程1就传递了"我的参数"字符串!工作线程2运行完了会通知等待的线程已发生事件.这里AutoResetEvent初始化的时候首先将信号设成false,工作线程2如果调用成功,将被设成true. asyncOpIsDone.WaitOne()阻塞当前线程,直到收到信号!

    再看下面的例子

     1 using System;
    2 using System.Collections.Generic;
    3 using System.Linq;
    4 using System.Text;
    5 using System.Threading;
    6
    7 namespace ConsoleApplication7
    8 {
    9 class Program
    10 {
    11 static void Main(string[] args)
    12 {
    13 Console.WriteLine("\n当前线程的HashCode:{0}", Thread.CurrentThread.GetHashCode().ToString());
    14 Console.WriteLine("当前应用域的名字为:{0}", AppDomain.CurrentDomain.FriendlyName);
    15 int workerThreads;
    16 int completionPortThreads;
    17
    18 AutoResetEvent asyncOpIsDone = new AutoResetEvent(false);//信号初始为空
    19 AutoResetEvent asyncOpIsDone2 = new AutoResetEvent(false);
    20 ThreadPool.QueueUserWorkItem(new WaitCallback(MyWork), asyncOpIsDone);
    21 ThreadPool.QueueUserWorkItem(new WaitCallback(MyWork1), asyncOpIsDone2);
    22 ThreadPool.GetMaxThreads(out workerThreads, out completionPortThreads);
    23 Console.WriteLine("得当前由线程池维护的辅助线程的最大数目:{0}", workerThreads);
    24 ThreadPool.GetMinThreads(out workerThreads, out completionPortThreads);
    25 Console.WriteLine("得当前由线程池维护的空闲辅助线程的最小数目:{0}", workerThreads);
    26 /*WaitHandle[] waithandles = new WaitHandle[2];
    27 waithandles[0] = asyncOpIsDone;
    28 waithandles[1] = asyncOpIsDone2;
    29 WaitHandle.WaitAll(waithandles); */
    30 //或者可以这样
    31 asyncOpIsDone.WaitOne();
    32 Console.WriteLine("MyWork结束");
    33 asyncOpIsDone2.WaitOne();
    34 Console.WriteLine("MyWork1结束");
    35 }
    36 static void MyWork(Object state)
    37 {
    38 Console.WriteLine("\n当前线程的HashCode:{0}", Thread.CurrentThread.GetHashCode().ToString());
    39 Console.WriteLine("当前应用域的名字为:{0}", AppDomain.CurrentDomain.FriendlyName);
    40 Thread.Sleep(2000);
    41 ((AutoResetEvent)state).Set();//表示工作已经完成
    42 }
    43 static void MyWork1(Object state)
    44 {
    45 Console.WriteLine("\n当前线程的HashCode:{0}", Thread.CurrentThread.GetHashCode().ToString());
    46 Console.WriteLine("当前应用域的名字为:{0}", AppDomain.CurrentDomain.FriendlyName);
    47 Thread.Sleep(1000);
    48 ((AutoResetEvent)state).Set();//表示工作已经完成
    49 }
    50
    51 }
    52 }

    运行结果为

    本例中可以详细看AutoRestEvent的用法MyWork1实际上先结束的,但是asyncOpIsDone需要等MyWork的信号!所以先输出了MyWork结束.这里还有一个东西我想说的就是WaitHandle,上面的例子已经给出了他的用法!他是AutoRsetEvent的基类.

    还有ThreadPool有一个函数RegisterWaitForSingleObject这个函数还是满有意思的!我这里就不再给出例子了!

    好了,今天就到这了!

  • 相关阅读:
    94. Binary Tree Inorder Traversal
    101. Symmetric Tree
    38. Count and Say
    28. Implement strStr()
    实训团队心得(1)
    探索性测试入门
    LC.278. First Bad Version
    Search in Unknown Sized Sorted Array
    LC.88. Merge Sorted Array
    LC.283.Move Zeroes
  • 原文地址:https://www.cnblogs.com/enuo/p/2280009.html
Copyright © 2011-2022 走看看