线程池新建的线程不能及时执行

zhangjunbo317 2013-09-04 01:06:28
碰到一个线程池应用的问题,定时器间隔一段时间,扫描数据库,有新任务就创建一个新线程,创建新线程的方法ThreadPool.QueueUserWorkItem,但是新创建的线程不能及时执行,需要等待其他任务有一个完成了,才能开始执行。我希望是新线程能够及时执行,大家有没有一些思路或者建议。
...全文
438 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhangjunbo317 2013-09-05
  • 打赏
  • 举报
回复
private ManualResetEvent eventTimer = new ManualResetEvent(false); 不加eventTimer.WaitOne();timer的回调方法就不会执行。如果用线程池来实现,如何避免线程阻塞呢?是不是要申明 与线程数同样多的AutoResetEvent,在每个线程方法的内部调用AutoResetEvent.Set();总之,还是想通过线程池来实现多线程,让windows自己去调度,请问可以从哪些方面改进。
人生导师 2013-09-04
  • 打赏
  • 举报
回复
引用 8 楼 sp1234 的回复:
[quote=引用 3 楼 lizhi3186575 的回复:] 因为ThreadPool.QueueUseWorkItem方法就是让任务进行排队的,所以在同一时刻只能有一个线程执行,所以你用这样的方式不能在相同时刻运行两个线程,不过你也对线程池进行管理的,具体参考下面文章: http://msdn.microsoft.com/en-us/magazine/dd419664.aspx 如果不喜欢文章中的建议,可以直接使用并行编程,使用Task类的方式来创建一个任务。并行编程的使用可以参考: http://msdn.microsoft.com/zh-cn/library/dd460693(v=vs.100).aspx
晕死。“同一时刻只能有一个线程执行”?呵呵[/quote] 回答错了,CSDN 这点不好,都不能更新和删除的
  • 打赏
  • 举报
回复
不知道你写的 eventTimer.WaitOne() 这是什么东东。 不过,有些人拿着异步线程的语法,却去进行“循环、阻塞”来模拟同步操作。这真是没有意义的事情。与其那样,你还不如就写一个简单的顺序过程就得了,搞什么线程呢? 看到循环、阻塞,你就应该担心这有可能是碰上线程“伪娘”了。
  • 打赏
  • 举报
回复
引用 3 楼 lizhi3186575 的回复:
因为ThreadPool.QueueUseWorkItem方法就是让任务进行排队的,所以在同一时刻只能有一个线程执行,所以你用这样的方式不能在相同时刻运行两个线程,不过你也对线程池进行管理的,具体参考下面文章: http://msdn.microsoft.com/en-us/magazine/dd419664.aspx 如果不喜欢文章中的建议,可以直接使用并行编程,使用Task类的方式来创建一个任务。并行编程的使用可以参考: http://msdn.microsoft.com/zh-cn/library/dd460693(v=vs.100).aspx
晕死。“同一时刻只能有一个线程执行”?呵呵
  • 打赏
  • 举报
回复
引用 楼主 zhangjunbo317 的回复:
碰到一个线程池应用的问题,定时器间隔一段时间,扫描数据库,有新任务就创建一个新线程,创建新线程的方法ThreadPool.QueueUserWorkItem,但是新创建的线程不能及时执行,需要等待其他任务有一个完成了,才能开始执行。我希望是新线程能够及时执行,大家有没有一些思路或者建议。
那你是用什么线程池啊?应该直接new Thread(...).Start()去执行。
zhangjunbo317 2013-09-04
  • 打赏
  • 举报
回复
private System.Threading.Timer timer;定义了局部变量timer,如果不加eventTimer.WaitOne();这条语句,timer的回调方法就不会被调用,这是为什么?
zhangjunbo317 2013-09-04
  • 打赏
  • 举报
回复
public void madeTimer() { ThreadPool.SetMinThreads(10, 10); ThreadPool.SetMaxThreads(200, 200); TimerCallback timerDelegate = new TimerCallback(madeThreads); //创建一个时间间隔为1s的定时器,如果线程池有闲置,就会创建新的任务线程 timer = new Timer(timerDelegate, null, 0, 200); Console.WriteLine("{0} 开始启动.\n", DateTime.Now.ToString("h:mm:ss.fff")); eventTimer.WaitOne(); } private void madeThreads(object m) { lock (this) { count++; int workerThreads; int ioIhreads; int iMaxCount; Console.WriteLine("{0} 计时器计时次数: {1}\n", DateTime.Now.ToString("h:mm:ss.fff"), count); string strSql = "select GID from ******"; ds = db.getDs(strSql); iMaxCount=ds.Tables[0].Rows.Count; Console.WriteLine("当前任务数量 {0}", iMaxCount); if (iMaxCount > 0) { for (int i = 0; i < iMaxCount; i++) { string GID = ds.Tables[0].Rows[i][0].ToString(); //为每个任务创建一个线程,执行单批次发送,并且在每个线程里面判断发送任务的状态,以避免当任务状态改变时,不能及时获取到状态,而继续执行发送。 //ThreadPool.QueueUserWorkItem(new WaitCallback(send), GID); ThreadPool.UnsafeQueueUserWorkItem(new WaitCallback(send), GID); } } else { Console.WriteLine("当前没有可执行的任务"); } ThreadPool.GetAvailableThreads(out workerThreads, out ioIhreads); Console.WriteLine("当前可用工作线程数量 {0}", workerThreads); } } private void send(object id) {\\操作主体} 用sleep似乎没用,线程池最大线程数200,但是只用了几十个线程,新加的线程还是在等待之前的任务执行完才能执行。
人生导师 2013-09-04
  • 打赏
  • 举报
回复
因为ThreadPool.QueueUseWorkItem方法就是让任务进行排队的,所以在同一时刻只能有一个线程执行,所以你用这样的方式不能在相同时刻运行两个线程,不过你也对线程池进行管理的,具体参考下面文章: http://msdn.microsoft.com/en-us/magazine/dd419664.aspx 如果不喜欢文章中的建议,可以直接使用并行编程,使用Task类的方式来创建一个任务。并行编程的使用可以参考: http://msdn.microsoft.com/zh-cn/library/dd460693(v=vs.100).aspx
xupeihuagudulei 2013-09-04
  • 打赏
  • 举报
回复
线程池里的纯种本身就是靠Windows来调度的,并不能保证立即执行
much0726 2013-09-04
  • 打赏
  • 举报
回复
那你其他的线程不要独占CPU,在必要的地方添加语句sleep(10)休眠下,就可以释放CPU给其他线程了,你所创建的线程就可以及时执行了。

110,568

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧