多线程基础知识(二)

线程池

  1. 因为每次创建线程、销毁线程都比较消耗 cpu 资源,因此可以通过线程池进行优化。线程池是一组已经创建好的线程,随用随取,用完了不是销毁线程,然后放到线程池中,供其他人用。
  2. 用线程池之后就无法对线程进行精细化的控制了(线程启停、优先级控制等)。
  3. ThreadPool 类的一个重要方法:
    1. static bool QueueUserWorkItem(WaitCallback callBack)
    2. static bool QueueUserWorkItem(WaitCallback callBack, object state)//用来传递一个参数给线程代码的
  4. 除非要对线程进行精细化的控制,否则建议使用线程池,因为又简单、性能调优又更好。

 

 1 static void Main(string[] args)
 2         {
 3             ThreadPool.QueueUserWorkItem(state =>
 4             {
 5                 for (int i = 0; i < 50; i++)
 6                 {
 7                     Console.WriteLine(i);
 8                 }
 9             });
10     }
View Code

 

 1 static void Main(string[] args)
 2         {
 3             
 4             for (int i = 0; i < 50; i++)
 5             {
 6                 //通过第二个参数给线程传值
 7                 ThreadPool.QueueUserWorkItem(state =>
 8                 {
 9                     Console.WriteLine(state);
10                 }, i);
11             }
12             Console.Read();
13         }    
View Code

三种异步编程模型

.Net 中很多的类接口设计的时候都考虑了多线程问题,简化了多线程程序的开发。不用自己去写 WaitHandler 等这些底层的代码。由于历史的发展,这些类的接口设计有着三种不同的风格:EAP(*)、APM(*)和 TPL。

目前重点用 TPL

1.EAP风格:类似于 Ajax 中的XmlHttpRequest,send 之后并不是处理完成了,而是在 onreadystatechange 事件中再通知处理完成

1 WebClient wc = new WebClient();
2 wc.DownloadStringCompleted += Wc_DownloadStringCompleted;
3 wc.DownloadStringAsync(new Uri("http://www.baidu.com"));
4 private void Wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
5 {
6 MessageBox.Show(e.Result);
7 }
View Code

  优点是简单,缺点是当实现复杂的业务的时候很麻烦;EAP 的类的特点是:一个异步方法配一个***Completed 事件。.Net 中基于 EAP 的类比较少

2.APM风格:是.Net 旧版本中广泛使用的异步编程模型。使用了 APM的异步方法会返回一个 IAsyncResult 对象,这个对象有一个重要的属性 AsyncWaitHandle,他是一个用来等待异步任务执行结束的一个同步信号。

 

APM 的特点是:方法名字以 BeginXXX 开头,返回类型为 IAsyncResult,调用结束后需要EndXXX。.Net 中有如下的常用类支持 APM:Stream、SqlCommand、Socket 等。

 

TPL风格:是.Net4.0后带来的新特性,更简洁、方便、现在.NET平台已经大面积使用

注意方法中如果有 await,则方法必须标记为 async,不是所有方法都可以被轻松的标记为 async。

WinForm 中的事件处理方法都可以标记为 async、MVC 中的 Action 方法也可以标记为 async、

控制台的 Main 方法不能标记为 async。

TPL 的特点:方法都以 XXXAsync 结尾,返回值类型是泛型的 Task<T>。TPL 让我们可以用线性的方式去编写异步程序,不再需要像 EAP 中那样搞一堆回调、逻辑跳来跳去了。

注意TPL中返回值直接使用即可,尽量不要使用其它一些方法的解析,比如:Result()

编写自己的一个异步方法

以async结尾最好,编写习惯

static Task<string> F2Async(){
return Task.Run(()=>{
System.Thread.Sleep(2000)
return "helloWord!";
});
}

 

posted @ 2017-10-12 11:38  大胖儿在努力  阅读(193)  评论(0编辑  收藏  举报