CLR线程池的工作者线程
来源:互联网 发布:侠盗无双0.4下载 软件 编辑:程序博客网 时间:2024/05/20 21:59
关于CLR线程池
使用ThreadStart与ParameterizedThreadStart建立新线程非常简单,但通过此方法建立的线程难于管理,若建立过多的线程反而会影响系统的性能。
有见及此,.NET引入CLR线程池这个概念。CLR线程池并不会在CLR初始化的时候立刻建立线程,而是在应用程序要创建线程来执行任务时,线程池才初始化一个线程。线程的初始化与其他的线程一样。在完成任务以后,该线程不会自行销毁,而是以挂起的状态返回到线程池。直到应用程序再次向线程池发出请求时,线程池里挂起的线程就会再度激活执行任务。这样既节省了建立线程所造成的性能损耗,也可以让多个任务反复重用同一线程,从而在应用程序生存期内节约大量开销。
工作者线程与I/O线程
CLR线程池分为工作者线程(workerThreads)与I/O线程 (completionPortThreads) 两种,工作者线程是主要用作管理CLR内部对象的运作,I/O(Input/Output) 线程顾名思义是用于与外部系统交换信息
通过QueueUserWorkItem启动工作者线程
ThreadPool线程池中包含有两个静态方法可以直接启动工作者线程:
一为 ThreadPool.QueueUserWorkItem(WaitCallback)
二为 ThreadPool.QueueUserWorkItem(WaitCallback,Object)
先把WaitCallback委托指向一个带有Object参数的无返回值方法,再使用 ThreadPool.QueueUserWorkItem(WaitCallback) 就可以异步启动此方法,此时异步方法的参数被视为null 。
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 //把CLR线程池的最大值设置为1000 6 ThreadPool.SetMaxThreads(1000, 1000); 7 //显示主线程启动时线程池信息 8 ThreadMessage("Start"); 9 //启动工作者线程10 ThreadPool.QueueUserWorkItem(new WaitCallback(AsyncCallback));11 Console.ReadKey();12 }13 14 static void AsyncCallback(object state)15 {16 Thread.Sleep(200);17 ThreadMessage("AsyncCallback");18 Console.WriteLine("Async thread do work!");19 }20 21 //显示线程现状22 static void ThreadMessage(string data)23 {24 string message = string.Format("{0}\n CurrentThreadId is {1}",25 data, Thread.CurrentThread.ManagedThreadId);26 Console.WriteLine(message);27 }28 }
使用 ThreadPool.QueueUserWorkItem(WaitCallback,Object) 方法可以把object对象作为参数传送到回调函数中。
下面例子中就是把一个string对象作为参数发送到回调函数当中。
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 //把线程池的最大值设置为1000 6 ThreadPool.SetMaxThreads(1000, 1000); 7 8 ThreadMessage("Start"); 9 ThreadPool.QueueUserWorkItem(new WaitCallback(AsyncCallback),"Hello Elva");10 Console.ReadKey();11 }12 13 static void AsyncCallback(object state)14 {15 Thread.Sleep(200);16 ThreadMessage("AsyncCallback");17 18 string data = (string)state;19 Console.WriteLine("Async thread do work!\n"+data);20 }21 22 //显示线程现状23 static void ThreadMessage(string data)24 {25 string message = string.Format("{0}\n CurrentThreadId is {1}",26 data, Thread.CurrentThread.ManagedThreadId);27 Console.WriteLine(message);28 }29 }
回调函数
.NET为 IAsyncResult BeginInvoke(AsyncCallback , object)准备了一个回调函数。使用 AsyncCallback 就可以绑定一个方法作为回调函数,回调函数必须是带参数 IAsyncResult 且无返回值的方法: void AsycnCallbackMethod(IAsyncResult result) 。在BeginInvoke方法完成后,系统就会调用AsyncCallback所绑定的回调函数,最后回调函数中调用 XXX EndInvoke(IAsyncResult result) 就可以结束异步方法,它的返回值类型与委托的返回值一致。
1 class Program 2 { 3 delegate string MyDelegate(string name); 4 5 static void Main(string[] args) 6 { 7 ThreadMessage("Main Thread"); 8 9 //建立委托10 MyDelegate myDelegate = new MyDelegate(Hello);11 //异步调用委托,获取计算结果12 myDelegate.BeginInvoke("Leslie", new AsyncCallback(Completed), null);13 //在启动异步线程后,主线程可以继续工作而不需要等待14 for (int n = 0; n < 6; n++)15 Console.WriteLine(" Main thread do work!");16 Console.WriteLine("");17 18 Console.ReadKey();19 }20 21 static string Hello(string name)22 {23 ThreadMessage("Async Thread");24 Thread.Sleep(2000); \\模拟异步操作25 return "\nHello " + name;26 }27 28 static void Completed(IAsyncResult result)29 {30 ThreadMessage("Async Completed");31 32 //获取委托对象,调用EndInvoke方法获取运行结果33 AsyncResult _result = (AsyncResult)result;34 MyDelegate myDelegate = (MyDelegate)_result.AsyncDelegate;35 string data = myDelegate.EndInvoke(_result);36 Console.WriteLine(data);37 }38 39 static void ThreadMessage(string data)40 {41 string message = string.Format("{0}\n ThreadId is:{1}",42 data, Thread.CurrentThread.ManagedThreadId);43 Console.WriteLine(message);44 }45 }如果想为回调函数传送一些外部信息,就可以利用BeginInvoke(AsyncCallback,object)的最后一个参数object,它允许外部向回调函数输入任何类型的参数。只需要在回调函数中利用 AsyncResult.AsyncState 就可以获取object对象。
1 class Program 2 { 3 public class Person 4 { 5 public string Name; 6 public int Age; 7 } 8 9 delegate string MyDelegate(string name);10 11 static void Main(string[] args)12 {13 ThreadMessage("Main Thread");14 15 //建立委托16 MyDelegate myDelegate = new MyDelegate(Hello);17 18 //建立Person对象19 Person person = new Person();20 person.Name = "Elva";21 person.Age = 27;22 23 //异步调用委托,输入参数对象person, 获取计算结果24 myDelegate.BeginInvoke("Leslie", new AsyncCallback(Completed), person); 25 26 //在启动异步线程后,主线程可以继续工作而不需要等待27 for (int n = 0; n < 6; n++)28 Console.WriteLine(" Main thread do work!");29 Console.WriteLine("");30 31 Console.ReadKey();32 }33 34 static string Hello(string name)35 {36 ThreadMessage("Async Thread");37 Thread.Sleep(2000);38 return "\nHello " + name;39 }40 41 static void Completed(IAsyncResult result)42 {43 ThreadMessage("Async Completed");44 45 //获取委托对象,调用EndInvoke方法获取运行结果46 AsyncResult _result = (AsyncResult)result;47 MyDelegate myDelegate = (MyDelegate)_result.AsyncDelegate;48 string data = myDelegate.EndInvoke(_result);49 //获取Person对象50 Person person = (Person)result.AsyncState;51 string message = person.Name + "'s age is " + person.Age.ToString();52 53 Console.WriteLine(data+"\n"+message);54 }55 56 static void ThreadMessage(string data)57 {58 string message = string.Format("{0}\n ThreadId is:{1}",59 data, Thread.CurrentThread.ManagedThreadId);60 Console.WriteLine(message);61 }62 }
- CLR线程池的工作者线程
- C多线程(三) -- CLR线程池的工作者线程
- CLR 的线程池
- CLR 的线程池
- CLR 的线程池
- CLR 的线程池
- CLR 的线程池
- CLR 的线程池
- CLR 的线程池
- 线程池中的工作者线程
- CLR线程池的I/O线程
- 工作者线程
- 简单的工作者线程封装
- UI线程、工作者线程
- CLR线程池
- 设置CLR线程池的默认大小
- ace 实现的线程池,可以用ACE_Svc_Handler作为工作者
- Linux内核默认工作者线程的处理
- ucos代码阅读(3)
- 在 Debian 上源码编译和安装 Nginx+PHP+FastCGI+MySQL
- How-to Guide: Perfect Windows Defender Uninstall
- SQLite模糊查找(like)
- VIM 高阶
- CLR线程池的工作者线程
- 写在研究生入学之前
- typedef和#define的区别
- 双击jar包出现:could not find the main class .和could not create the java virtual machine.win7/xp解决方法详解
- 经典递归应用--汉诺塔(C#语言版)
- Using Images as Buttons on Windows Phone 7
- 苹果开发者成惊弓之鸟:一封邮件引发的风波
- 第n+2周任务控制
- 混合使用Objective-C,C++和Objective-C++