多线程的问题,请达人帮忙。

lvlvlvlylyly 2013-01-23 08:55:58
我在程序里开了五百个线程,结果在想捕捉线程结束并退出的地方遇到了问题。

我明明开了五百个线程,全都是调用同一个sub,比较长,并在退出的时候,进行了捕捉,结果我发现,启动五百个线程,结束的时候,只发现了385个是正常退出,然后程序就没动静了,也就是说,还有115个线程,自己不知道什么时候自己挂掉了!!!

我不知道如何处理了,那个sub比较长,涉及到好几种不种的操作,有网页,有数据库,就不贴出详细代码了。

我就是不明白,线程会在何种情况下,自己挂掉,对这种自己挂掉的线程,应该通过什么方法来捕捉呢。

另:在这些线程里面,为了控制一个相同的数据集,我使用了一个DO LOOP的循环来阻塞线程,这个循环是无限的,直到一个变量为TRUE才往下走,感觉会不会这里出了问题。如果是的话,应该采取何种方法来阻塞线程呢。。。。。谢谢指点。。
...全文
358 41 打赏 收藏 转发到动态 举报
写回复
用AI写文章
41 条回复
切换为时间正序
请发表友善的回复…
发表回复
lvlvlvlylyly 2013-01-24
  • 打赏
  • 举报
回复
问题解决了,呵呵 我在所有读取公共变量的地方,用了一个 monitor.enter(me) monitor.exit(me) 用这个包起来就可以了!! 呵呵,至于其余的,什么CPU百分之百呀什么的,关我个叼事,哈哈 接下来搞停止所有线程的工作了,我现在的方法不好,我是用了一变量。。。 有什么好建议吗。。
lvlvlvlylyly 2013-01-24
  • 打赏
  • 举报
回复
多线程同时取消也搞定了,呵呵,这个还是很简单,只要解决了同步,基本上也就没啥问题了,, 谢谢楼上几位了。。结贴。
lvlvlvlylyly 2013-01-23
  • 打赏
  • 举报
回复
SyncLock Thread.CurrentThread end SyncLock 老兄,我用SyncLock可以达到目的吗??
lvlvlvlylyly 2013-01-23
  • 打赏
  • 举报
回复
没异常,这个ThreadState.Aborted就是异常引起的非正常结束,它之后,就马上是stopped了。所以能捉到这个也可以用了!!
lvlvlvlylyly 2013-01-23
  • 打赏
  • 举报
回复
哦,好的,我再看看,查查百度,其实我以前没开过这么多线程,最多开一两个,这次实在不行了,上千个网页,不开几百个线程,实在搞不定了,谢谢你的热心!!你给个关键词,我才好百度。。。。
ViewStates 2013-01-23
  • 打赏
  • 举报
回复
你catch到的异常信息呢? vb.net里面也有WaitHandle,EventWaitHandle的啊。
lvlvlvlylyly 2013-01-23
  • 打赏
  • 举报
回复
引用 5 楼 ViewStates 的回复:
已回复楼主信了。
ThreadState.Aborted,我在catch里面加上了这个判断,果然发现很多很多死掉的线程!! 谢谢你的私信,我水平有限,不过我感觉到,我用的那种死循环的方法肯定是不好的,其实我在用的时候,也想到了CPU的问题,但我只要达到目的就行。呵呵。。
   Catch Ex As Exception
             
               
   Finally
            If ThreadState.Aborted Then
                        Debug.Print("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
                    End If
                End Try
你帮我看看这个地方,是什么原因引起的ThreadState.Aborted呢,VB.net里面有没有简单点的方法让一个线程可以单独运行,阻塞掉别的线程呢,C#里面有个WaitOne,可vb.net里不知道是什么呀。。。
ViewStates 2013-01-23
  • 打赏
  • 举报
回复
在你线程执行的委托方法中用try catch finally 包起来,然后在finally中输出一段标示
lvlvlvlylyly 2013-01-23
  • 打赏
  • 举报
回复
靠,还是不对,我实在不知道哪里出了毛病,到处都debug了一下,实在发现不了问题了。草 真的不知道那些线程去哪了。。。。。。。。一身汗!!!
ViewStates 2013-01-23
  • 打赏
  • 举报
回复
已回复楼主信了。
  • 打赏
  • 举报
回复
引用 3 楼 lvlvlvlylyly 的回复:
找到原因了,原来是System.Net.WebException 的错误,本来我已经用了try...end try来捕错了,我以为它弹错之后还能继续往下走,谁知道原来它弹错之后,就直接挂了。。
调试程序的时候注释掉try catch
lvlvlvlylyly 2013-01-23
  • 打赏
  • 举报
回复
找到原因了,原来是System.Net.WebException 的错误,本来我已经用了try...end try来捕错了,我以为它弹错之后还能继续往下走,谁知道原来它弹错之后,就直接挂了。。
ViewStates 2013-01-23
  • 打赏
  • 举报
回复

  public class WorkHelper : IDisposable
    {
        int totalCounts;
        ManualResetEvent mre;

        public WorkHelper(int totalWorkCounts)
        {
            mre = new ManualResetEvent(false);
            totalCounts = totalWorkCounts + 1;
        }

        public void CountDown()
        {
            if (Interlocked.Decrement(ref totalCounts) <= 0)
            {
                mre.Set();
            }
        }

        public void WaitAll()
        {
            CountDown();
            mre.WaitOne();
        }



        #region IDisposable 成员

        void IDisposable.Dispose()
        {
            ((IDisposable)mre).Dispose();
        }

        #endregion
    }
~~~
using(WorkHelper wh=new WorkHelper(500))
{
 for(int i=0;i<500;i++)
 {
  ThreadPool.QueueUserWorkItem(_=>{
   //bla, bla, bla....
   wh.CountDown();
 });
  wh.WaitAll();
 }
 //final exit 
}

  • 打赏
  • 举报
回复
在sub最后加个count++,看看count是多少
ViewStates 2013-01-23
  • 打赏
  • 举报
回复
针对int+int这样的过程,实际上它并不是一个原子操作,这个在单线程模式下是不会有问题,但是在多线程下这种问题就会暴露出来,通过Interlocked对象提供的各种静态方法可以将这个过程“变成”原子操作。 如果你只是想简单的控制线程数,就按照你的需求需要限制最大线程数小于255(其实并不是线程多就能过加快整个系统的运行),实际可以将你委托方法直接交由线程池执行,并设置线程池的最大线程数即可。
lvlvlvlylyly 2013-01-23
  • 打赏
  • 举报
回复
生产消费者模式我就不懂了,自产自销模式我就很懂了,哈哈 百度了一下,头都晕了。。。这里面还确实蛮有意思的。。 哎,可惜时间紧张。管不了那么许多了。。。 我已经干了一天一夜了,太累了,先睡一觉,起来再研究吧。。。确实挺好玩的 System.Threading.Interlocked.Increment(XCNum)主要我不太清楚,这里这个保护,难道没有让其它的线程等待吗,为什么加了个延时之后,反倒看到五百了。。。也就是说,所有的线程都在顺序地访问这个变量。。 那我到底应该怎么启动所有线程,我原来是在一个循环里面,NEW完了之后就直接START的,现在看来,这样好象有问题。 另外,就是线程结束的时候,好象也不能这么用变量去减,因为我发现实际上,好象有时候是先出零,后出4,3,2,1。。。为什么会这样啊。。。 哎。。。。。年轻的时候就被关进去了,放出来都三十好几了。。。。什么都没学到,虚度了光阴。。。
xyz378704 2013-01-23
  • 打赏
  • 举报
回复
你想看到不一样的是吧,简单的方式 Dim QSZ As Integer Dim intI As Integer Dim iii As Integer 'XCNum = XCNum + 1 iii = System.Threading.Interlocked.Increment(XCNum) Thread.Sleep(60 * 1000) 这里打印iii的值,Sleep 1分钟是为了确保线程全部开启 你的程序有很大的问题,建议改为生产者消费者模式,
lvlvlvlylyly 2013-01-23
  • 打赏
  • 举报
回复
ReadWriteLock.AcquireReaderLock(System.Threading.Timeout.Infinite) System.Threading.Interlocked.Decrement(XCNum) ' 此处执行数据操作 ReadWriteLock.ReleaseReaderLock() ' 释放读取锁 我用了这个,好象好点了,能开到三百线程了。。。呵呵, 我就一顿乱搞。。。。乱试,是不是读变量的时候也要加锁哦。。。。 哎,不是科班出身呀。。。基础不好。。。。只能乱搞了。。。。见笑见笑。。。
lvlvlvlylyly 2013-01-23
  • 打赏
  • 举报
回复
Thread.Sleep(100) Thread.Sleep(100) Thread.Sleep(100) Dim QSZ As Integer Dim intI As Integer 'XCNum = XCNum + 1 System.Threading.Interlocked.Increment(XCNum) 这段代码是最开始运行的,还没有走到结束呀。。。。。怎么会一运行起来就结束了呢。。。。 我退出循环用的是比较表格的行数,这个行数是固定的,线程起来之后,这个变量是不会变的。。而且这个数字很大,有几千行,怎么可能一运行就退出了呢。。。
lvlvlvlylyly 2013-01-23
  • 打赏
  • 举报
回复
那你能不能告诉我如何获取启动的线程数量呢?我试了上十次,只有一次打印出了三百,我实际上就是开了三百个线程,但其余每次都打不到这个数字。。。
加载更多回复(21)

16,549

社区成员

发帖
与我相关
我的任务
社区描述
VB技术相关讨论,主要为经典vb,即VB6.0
社区管理员
  • VB.NET
  • 水哥阿乐
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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