欢迎来到山村网

C# ThreadPool.QueueUserWorkItem典型案例详解

2019-03-02 11:28:46浏览:421 来源:山村网   
核心摘要:  using System;  using System.Collections.Generic;  using System.Threading;  namespace ThreadPoolTest  {  cl

  using System;

  using System.Collections.Generic;

  using System.Threading;

  namespace ThreadPoolTest

  {

  class Program

  {

  static void Main(string[] args)

  {

  //声明一个Action委托的List,添加一些委托测试用

  List actions = new List

  {

  ()=>{Console.WriteLine("A-1");},

  ()=>{Console.WriteLine("A-2");},

  ()=>{Console.WriteLine("A-3");},

  ()=>{Console.WriteLine("A-4");}

  };

  //遍历输出结果

  foreach (var action in actions)

  {

  ThreadPool.QueueUserWorkItem(state => action() , null);

  }

  Console.ReadKey();

  }

  }

  }

  这个很意外的结果如下:

C# ThreadPool.QueueUserWorkItem典型案例详解 山村

  为什么如此呢:

  我分析下,首先大家都知道创建一个线程是需要时间的,线程池作为一个管理线程的对象操作简单,但是涉及到具体细节的时候却很难控制,其原理是当线程池收到请求以后,则从线程池中找到一个闲的线程分配给它,然后启动。 但是线程池的线程从创建到启动需要时间,但是主线程的循环显然只是瞬间完成,完全没必要夹杂在线程池的等待中,因此出现了主线程执行完循环最后是的线程池收到的请求委托是列表中的最后一个,如何解决?

  方式一: Thread.Sleep(1);

  博主说对于Thread.Sleep(N)的方式难以接受,其实只要细细去分析原理,就能知道这个方式是可以接受甚至是微妙的,Thread.Sleep(N)是对当前线程阻塞一定时间,那这个处理不论是主线程还是线程池中的线程都是有效果的,至少为线程池中的线程的请求与启动赢得了时间。当然在这里阻塞的线程一定是主线程,使其不能得到CPU时间,这样也就成功了得到预期结果。

  后来又采取另外一种方式,

  方式二:

  foreach (var action in actions)

  {

  var Tempaction = action;

  ThreadPool.QueueUserWorkItem(state => Tempaction() , null);

  }

  将循环中的变量存储到一个临时变量中,为什么这样行呢?

  大家知道线程池是有请求就为其分配一个自由线程与其工作,当每一次循环中的变量不同也就是对象不同时这时候每次请求出现差异,当然线程池必须为每一个做准备,不同于把循环变量直接作为请求,这时候每一个请求就按顺序依次准备好依次启动。当然也就成功了。

(责任编辑:豆豆)
下一篇:

编写C语言程序需要注意的问题

上一篇:

使用Visual C++防御功能保护您的代码

  • 信息二维码

    手机看新闻

  • 分享到
打赏
免责声明
• 
本文仅代表作者个人观点,本站未对其内容进行核实,请读者仅做参考,如若文中涉及有违公德、触犯法律的内容,一经发现,立即删除,作者需自行承担相应责任。涉及到版权或其他问题,请及时联系我们 xfptx@outlook.com