• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

C# 线程池的使用 终止线程池中的队列

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

C#的线程池使用起来还是非常简单的,这里记录一下。

根据http://blog.csdn.net/chen_zw/article/details/7939834里的描述这里记录一下C#线程池的特点

  • 一个进程有且只能管理一个线程池。
  • 线程池线程都是后台线程(即不会阻止进程的停止)
  • 每个线程都使用默认堆栈大小,以默认的优先级运行,并处于多线程单元中。超过最大值的其他线程需要排队,但它们要等到其他线程完成后才启动。
  • 在CLR 2.0 SP1之前的版本中,线程池中 默认最大的线程数量 = 处理器数 * 25, CLR 2.0 SP1之后就变成了 默认最大线程数量 = 处理器数 * 250,线程上限可以改变,通过使用ThreadPool.GetMax+Threads和ThreadPool.SetMaxThreads方法,可以获取和设置线程池的最大线程数。
  • 默认情况下,每个处理器维持一个空闲线程,即默认最小线程数 = 处理器数。
  • 当进程启动时,线程池并不会自动创建。当第一次将回调方法排入队列(比如调用ThreadPool.QueueUserWorkItem方法)时才会创建线程池。
  • 在对一个工作项进行排队之后将无法取消它。
  • 线程池中线程在完成任务后并不会自动销毁,它会以挂起的状态返回线程池,如果应用程序再次向线程池发出请求,那么这个挂起的线程将激活并执行任务,而不会创建新线程,这将节约了很多开销。只有线程达到最大线程数量,系统才会以一定的算法销毁回收线程。

在使用线程池的时候,需要初始化其状态

ManualResetEvent eventX = new ManualResetEvent(false);//表示线程池的状态 false代表非终结状态

根据https://www.cnblogs.com/tianboblog/p/5393444.html介绍:

当初始化为true时,为终止状态

static ManualResetEvent _mre = new ManualResetEvent(true);

当初始化为false时,为非终止状态

static ManualResetEvent _mre = new ManualResetEvent(false);
 

终止状态时WaitOne()允许线程访问下边的语句

非终止状态时WaitOne()阻塞线程,不允许线程访问下边的语句

把非终止状态改为终止状态用Set()方法

把终止状态改为非终止状态用Reset()方法

//按钮事件

private void btnBatchSend_Click(object sender, RoutedEventArgs e)
{

eventX.Reset();
ThreadPool.SetMinThreads(1, 1);//设置线程池在新请求预测中维护的空闲线程数
ThreadPool.SetMaxThreads(10,10);//设置可以同时处于活动状态的线程池的最大请求数目

以上两句必须都有才行

//循环设置执行对象,

for (int i = 0; i < list.Count; i++)
{

 ThreadPool.QueueUserWorkItem(tranSend, oj);//

}

eventX.WaitOne();//当是非终结状态时,会阻塞主线程
eventX.Reset();//设置为非终结状态

}

worker.RunWorkerCompleted += (o, ea) =>
{
//sb.Append("主线程执行完毕");
//this.txt_cansole.Text = sb.ToString();
this.btnBatchCheck.IsEnabled = true;
this.btnBatchSend.Visibility = Visibility.Visible;
this.btnStopSend.Visibility = Visibility.Collapsed;
};
this.btnBatchCheck.IsEnabled = false;
this.btnBatchSend.Visibility = Visibility.Collapsed;
this.btnStopSend.Visibility = Visibility.Visible;
worker.RunWorkerAsync();

 

//每个线程将会执行的任务

private void tranSend(object order)
{

Order s = order as Order;

//当是最后一个order 或者 用户点了停止按钮时
if (s.IsLas || Break)
{
eventX.Set();//当点了停止按钮时,将线程池信号灯状态设置为终结状态这时会通知主线程继续往下执行
return;
}

//真正的执行任务代码
s.SendMessage = ">>";
s.ItemStatus = 1; /

}

 

可以看出来熟练C#线程池的使用主要是控制好信号灯的状态,当主线程往下执行时,for循环里的代码会很快执行完毕,虽然最多只允许了十个线程同时活动,但十个之后的对象已经加入了队列,需要中断时,需要在执行任务里去自行判断。

if (s.IsLas || Break)
{
eventX.Set();//当点了停止按钮时,将线程池信号灯状态设置为终结状态这时会通知主线程继续往下执行
return;
}


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C# 扩展方法集发布时间:2022-07-10
下一篇:
C#Note4:XML序列化和反序列化(含加密解密等)前言1.XML序列化和反序列化 ...发布时间:2022-07-10
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap