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这个函数还是满有意思的!我这里就不再给出例子了!

好了,今天就到这了!

原文地址:https://www.cnblogs.com/enuo/p/2280009.html