请教一个ThreadPool.QueueUserWorkItem问题,分儿很多

失足成万古风流人物 2014-09-23 05:18:19
多个线程不小心用了同一个数据库连接,导致一个线程正在使用的连接被其他线程关闭。
一次dao.dosome();过程是打开连接,操作数据库,关闭连接。
问题是:为什么3、4分钟才会执行一次ThreadPool.QueueUserWorkItem(new WaitCallback(process), p);,还会偶尔出现两个线程共用这个连接呢?难道3、4分钟完成不了一次数据库操作(只是插入一条数据)?

代码描述如下:

//这条语句大概3、4分钟才会执行一次
ThreadPool.QueueUserWorkItem(new WaitCallback(process), p);

process(p)
{
dao.dosome();
}
...全文
515 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
abc2363789187 2014-10-04
  • 打赏
  • 举报
回复
从网上搜索到,解决多线程读写冲突的方法有几种。 1)lock互斥:它可以把一段代码定义为互斥段。互斥段在一个时刻内只允许一个线程执行; lock(this) { ... } 2)monitor类:公用一个对象时来锁定这个对象。一个线程只有获得这把锁才能对该对象进行操作; Monitor.Enter(对象); Monitor.Exit(对象); Monitor.Pulse(); 3)mutext类:互斥对象; Mutex.WaitAll(互斥对象实例); Mutex.WaitOne();
E次奥 2014-09-29
  • 打赏
  • 举报
回复
你的数据库连接是不是静态方法,共用连接了!
  • 打赏
  • 举报
回复
么有人了么,
  • 打赏
  • 举报
回复
引用 21 楼 porenasckx 的回复:
你的数据库连接是不是静态方法,共用连接了!
跟数据库连接没关系,我的问题在20楼
  • 打赏
  • 举报
回复
引用 22 楼 jobscq 的回复:
Thread.Sleep()是个静态方法好吧!!休眠的时候肯定是所有线程都睡了呀!ThreadPool是有空闲线程的时候才执行,大家都忙着睡觉呢,谁有空来执行你的任务?
Thread.Sleep()休眠当前线程,让出cpu
jobscq 2014-09-29
  • 打赏
  • 举报
回复
Thread.Sleep()是个静态方法好吧!!休眠的时候肯定是所有线程都睡了呀!ThreadPool是有空闲线程的时候才执行,大家都忙着睡觉呢,谁有空来执行你的任务?
  • 打赏
  • 举报
回复

void thread1()
{
    while (true)
	{
	    sleep(500);
	}
}

void thread2()
{
    ThreadPool.QueueUserWorkItem(new WaitCallback(process), p);
}

void process(object p)
{
    dao.insert(p);
}
线程1阻塞的时候, 线程池中的任务一直得不到执行
  • 打赏
  • 举报
回复
引用 8 楼 l397870376 的回复:
那你只能 让线程 等待了 如果 一个线程正在执行的话那么其他线程等待
我问题的意思是:一个任务扔给线程池后,3、4分钟一直没能得到执行,直到下一个任务来了,这两个任务才一块儿开始执行,这是为什么?
_小黑_ 2014-09-24
  • 打赏
  • 举报
回复
那你只能 让线程 等待了 如果 一个线程正在执行的话那么其他线程等待
  • 打赏
  • 举报
回复
没人赐教了么
  • 打赏
  • 举报
回复
比如像你上面说的的,感觉只是执行了一个insert就要那么久 很简单,你先把那句执行代码注释掉,看看是不是还要那么久?把你觉得可能费时的操作逐个注释掉,直到找到它
  • 打赏
  • 举报
回复
引用 16 楼 u012071890 的回复:
[quote=引用 13 楼 dongxinxi 的回复:] ThreadPool.QueueUserWorkItem(new WaitCallback(process), p); 这个语句几乎就是瞬间就执行完了,不管排队成功没有都是 关键要看你那个代码是什么时候被调用的,比如放在定时器里了 或者是收到什么请求的时候才会去执行的,这跟process(p)本身执行要多久一点关系都没有
我并不是纠结往线程池投任务的时间,纠结的是process(p)为什么一直没得到执行,而是直到第二个任务来到后,两个任务才一起开始执行[/quote] 那就要看process(p)本身做了什么事情,有没有一次只供一个线程访问的资源被锁了
  • 打赏
  • 举报
回复
引用 13 楼 dongxinxi 的回复:
ThreadPool.QueueUserWorkItem(new WaitCallback(process), p); 这个语句几乎就是瞬间就执行完了,不管排队成功没有都是 关键要看你那个代码是什么时候被调用的,比如放在定时器里了 或者是收到什么请求的时候才会去执行的,这跟process(p)本身执行要多久一点关系都没有
我并不是纠结往线程池投任务的时间,纠结的是process(p)为什么一直没得到执行,而是直到第二个任务来到后,两个任务才一起开始执行
  • 打赏
  • 举报
回复
引用 12 楼 Z65443344 的回复:
另外两个线程是否设置过线程优先级? 此外,另外两个线程的串口接收是同步还是异步,如果是同步,是while一直循环,还是加了sleep?
没有线程优先级,串口接收中确实有个类似while(flag){sleep(500);},等待flag才会结束while,而flag正是在给线程池扔完任务后才flag = false
  • 打赏
  • 举报
回复
引用 12 楼 Z65443344 的回复:
另外两个线程是否设置过线程优先级? 此外,另外两个线程的串口接收是同步还是异步,如果是同步,是while一直循环,还是加了sleep?
没有线程优先级,串口接收中确实有个类似while(flag){sleep(500);},等待某信号才会结束等待
  • 打赏
  • 举报
回复
ThreadPool.QueueUserWorkItem(new WaitCallback(process), p); 这个语句几乎就是瞬间就执行完了,不管排队成功没有都是 关键要看你那个代码是什么时候被调用的,比如放在定时器里了 或者是收到什么请求的时候才会去执行的,这跟process(p)本身执行要多久一点关系都没有
於黾 2014-09-24
  • 打赏
  • 举报
回复
另外两个线程是否设置过线程优先级? 此外,另外两个线程的串口接收是同步还是异步,如果是同步,是while一直循环,还是加了sleep?
  • 打赏
  • 举报
回复
引用 10 楼 Z65443344 的回复:
你确定是因为线程池没有执行,而不是其他地方也使用了这个方法? 有个办法可以测试,数据库中加2列,时间型 然后任务给线程池的时候,传递一个当前时间进去 往数据库里插入的时候,将之前传递的时间和当前时间一起插入数据库 然后等出问题的时候,你看这两个时间到底差多少.
还有一点我没提,程序中除了这个线程池里的任务,还有另外两个线程,每个都是大概5百毫秒做一个串口接收并解析数据(解析时间很短不用考虑)。难道是这两个线程一直占用cpu,线程池里任务得不到时间片?
於黾 2014-09-24
  • 打赏
  • 举报
回复
你确定是因为线程池没有执行,而不是其他地方也使用了这个方法? 有个办法可以测试,数据库中加2列,时间型 然后任务给线程池的时候,传递一个当前时间进去 往数据库里插入的时候,将之前传递的时间和当前时间一起插入数据库 然后等出问题的时候,你看这两个时间到底差多少.
  • 打赏
  • 举报
回复
引用 5 楼 sunny906 的回复:
总的来说,造成"3、4分钟"的原因,除了线程互斥,还有数据库锁
你理解错了,3、4分钟是说往线程池抛任务的频率,任务就简单的一个数据库插入操作,按说线程池常态下最多有一个任务,这个任务有3、4分钟执行不完的可能?
加载更多回复(5)

110,539

社区成员

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

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

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