如何关闭子线程?征集析构函数与多线程的讨论!

下面的代码是可以执行,大家都来说说为什么这个程序不会自动退出?
也就是说mian函数执行完毕后,为什么.net不会释放ThreadEx对象?

using System;
using System.Threading;

public class ThreadEx : IDisposable{    
    
private Thread thread;
    
private volatile bool bExit;
    
public ThreadEx(){
        Console.WriteLine(
"ThreadEx output");
        bExit 
= false;
        thread 
= new Thread(OnThread);
        thread.Start();
    }


    
~ThreadEx(){
        Console.WriteLine(
"~ThreadEx output");
        bExit 
= true;
    }


    
private void OnThread(){
        
while(true){
            
if(bExit){
                
break;
            }

            Console.WriteLine(
"Thread output");
            Thread.Sleep(
1000);
        }

        Console.WriteLine(
"Thread exit");
    }


    
private void Close(){
        bExit 
= true;
    }


    
public void Dispose() {
        
// TODO:  添加 ThreadEx.Dispose 实现
        Console.WriteLine("~Dispose output");
        bExit 
= true;
    }


    
static void Main(){
        ThreadEx threadEx 
= new ThreadEx();
    }

}
posted @ 2007-09-28 16:42 dannyr|一个都不能少! 阅读(2436) 评论(16)  编辑 收藏 网摘 所属分类: .Net技术

  回复  引用  查看    
#1楼 2007-09-28 16:47 | 绿蚂蚁      
第二句main写错了
GC不会立即回收它的
  回复  引用  查看    
#2楼 [楼主]2007-09-28 16:53 | dannyr|一个都不能少!      
“第二句main写错了”
怎么解?
  回复  引用  查看    
#3楼 2007-09-28 17:04 | henry      
看过一本书说过托管代码下的释构函执行是不可控的
  回复  引用  查看    
#4楼 2007-09-28 17:06 | XiaoFaye      
调试时查看它的IL代码就知道发生什么事了。。。。
  回复  引用  查看    
#5楼 2007-09-28 17:34 | Adrian H.      
thread.IsBackground = true;
线程就会随着主线程关闭而关闭了。

  回复  引用  查看    
#6楼 [楼主]2007-09-28 17:46 | dannyr|一个都不能少!      
--引用--------------------------------------------------
Adrian H.: thread.IsBackground = true;
线程就会随着主线程关闭而关闭了。

--------------------------------------------------------
不错,可惜不能在析构函数里控制关闭线程,清理资源之类的动作,因为线程已经关闭了。
  回复  引用  查看    
#7楼 2007-09-28 18:39 | 瑞克      
试试设置 threadEx 为 null。
然后调用GC的collect。
  回复  引用    
#8楼 2007-09-28 21:13 | Kerry Jiang [未注册用户]
IsBackground = true
  回复  引用  查看    
#9楼 2007-09-28 21:48 | Kingthy      
你的代码里永远都还有线程在跑,所以threadEx一真在被引用着.所以就不会被回收掉,也就是永远没有调用到折构函数...
  回复  引用  查看    
#10楼 2007-09-28 21:52 | Kingthy      
而你的例子继承了IDisposable接口,Main里的代码改成这样就好多了.呵呵
using (ThreadEx threadEx = new ThreadEx())
{
}
还是@henry说的,折构函数是不可控的.它是在对象没有引用并GC回收此对象时才会调用的方法.
  回复  引用  查看    
#11楼 2007-09-28 22:43 | 大石头      
非常简单,thread专门有一个异常,用于退出的。线程函数内,死循环内,捕获这个异常,一旦捕获,就退出循环,线程外部有专门的函数来引发这个异常。

简单一点的理解就是,我要你出错,出错时具体怎么做,由你自己处理。
  回复  引用  查看    
#12楼 2007-09-28 23:15 | Adrian H.      
--引用--------------------------------------------------
dannyr|一个都不能少!: --引用--------------------------------------------------
Adrian H.: thread.IsBackground = true;
线程就会随着主线程关闭而关闭了。

--------------------------------------------------------
不错,可惜不能在析构函数里控制关闭线程,清理资源之类的动作,因为线程已经关闭了。
--------------------------------------------------------
在外面调用Dispose来清理线程引用的对象。你敢完全依靠Finalize来清理?
  回复  引用    
#13楼 2007-09-28 23:39 | fredchan [未注册用户]
private void OnThread(){
while(true){
if(bExit){
break;
}
Console.WriteLine("Thread output");
Thread.Sleep(1000);
}
Console.WriteLine("Thread exit");
}
其中,while(true){
if(bExit){
break;
}
Console.WriteLine("Thread output");
Thread.Sleep(1000);
}
一直在执行,因为对象一直在运行,因此不可能调用析构函数~ThreadEx()
这个问题比较低级
  回复  引用    
#14楼 2007-09-29 09:38 | 访客 [未注册用户]
private void OnThread(){
while(true){
if(bExit){
break;
}
Console.WriteLine("Thread output");
Thread.Sleep(1000);
}
Console.WriteLine("Thread exit");
}
上面的函数总是在执行,他不可能自动退出的
  回复  引用  查看    
#15楼 2007-09-29 11:20 | 徐少侠      
基本同意13、14楼的意见


  回复  引用  查看    
#16楼 2007-09-29 11:41 | 亚历山大同志      
代码逻辑的问题,不是析构的问题,完毕

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2007-09-28 17:51 编辑过
Google站内搜索


China-pub 计算机图书网上专卖店!6.5万品种 2-8折!
近千种 9-95 新二手计算图书火热销售中!

相关文章:

相关链接: