try {
while(true) {
}
} catch(ThreadAbortException abort_ex) {
Thread.ResetAbort();
} finally {
while(true) {
}
}
上面为线程执行的C#代码,很简单。问题是:如何在不终止进程的条件下终止此线程?
注意:不要调用Environment.Exit()、Application.Exit()、Application.ExitThread()等导致进程终止的方法!
本菜邮箱:[email protected],欢迎大侠赐教 :D

解决方案 »

  1.   

    已经通过代码证实:调用Thread.Abort()无法关闭此线程。高手在哪里?!
      

  2.   

    连续调用两次Thread.ResetAbort(); 
    或者连续抛出两次ThreadAbortException 异常
      

  3.   


    不要修改线程运行的代码,必须在线程外面终止该线程。
    heyang1985可以说详细点吗?
      

  4.   

    try { 
    while(true) { 

    } catch(ThreadAbortException abort_ex) { 
    Thread.ResetAbort(); 
    } finally { 
    while(true) { 

    } 改为
    bool bRuning = true;try {
      while(bRunning){
      }
    }
    catch(ThreadAbortException abort_ex) { 
      bRunning = false; 
    } finally { 
    while(bRunning) { 

    } 在发生异常时会自然中止,或者可以在线程外面令bRunning = false也可以令线程中止
      

  5.   

    如果是线程外中断,   就可以用TerminateThread,   线程内用ExitThread
      

  6.   

    在DotNet1.0或1.1下可能通过两次Thread.Abort来终止该线程,但2.0后设计上就不愿看到这种情况。2.0后为了系统健壮和更好的清理(清理不能被打断),当运行在finally区块内或P/Invoke中,ThreadAbortException是不会被引发的。下面是Thread.Abort的文档原文...线程不一定会立即中止,或者根本不中止。如果线程在作为中止过程的一部分被调用的 finally 块中做非常大量的计算,从而无限期延迟中止操作,则会发生这种情况。static void ThreadEntry()
    {
        try{}
        finally
        {
            while (true) ;
        }
    }我在DotNet 2.0下的试验中,TerminateThread(臭名昭著的API)可以终止该线程。但这种强迫中止的情况下谁也不能保证程序还能处于正常的状态。Thread.Abort以及TerminateThread都是微软极力不推荐的。我的立场也是一样,解释finally和TerminateThread只是为了更好的理解,而不是鼓励朋友们用Thread.Abort来停止线程。
    static void Main(string[] args)
    {
        int threadId = 0;
        Thread t = new Thread( new ThreadStart(delegate
        {
            threadId = AppDomain.GetCurrentThreadId();
            ThreadEntry();
        }));
        t.Start();    Console.ReadLine();    IntPtr tHandle = OpenThread(THREAD_TERMINATE, 0, threadId);
        int ok = TerminateThread(tHandle, -1);
        CloseHandle(tHandle);
        
        Console.ReadLine();
    }
      

  7.   

    To:Syping1、lowsong:不能修改线程代码的执行代码,要修改的话就不是难题了!
    gomoku的论述很精彩,目前尚未在.net 2.0以上版本发现终止此线程的方法。TerminateThread需要提供线程句柄,很遗憾.net没有提供获取线程句柄的API。
      

  8.   

    To:Supermcjt、Syping1、lowsong
    再次说明:不要修改线程代码!此代码是特例。顺便说明一下为什么会提出此问题:主线程载入指定文件中的程序集并在非后台辅助线程执行程序集中的代码,需要提供停止执行的机制。如果程序集中的代码如问题中那样的话,此辅助线程将无法停止,势必会留下系统隐患。再等两天,若还没有办法解决,就结贴 :D
      

  9.   


    Thread.About 只是提交一个终止线程的请求,你去注意一下thread的threadstate域,它告诉你将是aboutrequest!你得等它自己达到abouted状态。但是,你需要了解的是,如果程序进去了while,那么你任何强制中断或者强行退出的做法都是非法而且会引发莫名异常的。所以你不能让while内的程序去抛出异常让外部来处理,你应该做的是,把try -catch块放到while里面,出错的话要将while给break掉!之后再做进一步的处理。建议,不要尝试做任何在非break的情况下,从while里面跳出循环的任何尝试。说完了。
      

  10.   

    所以这根本就不是线程API的问题,它很安全,而是你的代码做法很黄很暴力,是不被允许的。
      

  11.   

    这里不讨论代码是否符合规范,我只是指出了一个在.net 2.0以上版本可能(目前为止)导致线程无法关闭的代码特例。
    欢迎继续拍砖 :D
      

  12.   

    thread t=Thread.CurrentThread;
    try
    {
    t.Abort();
    }
    catch(ThreadAbortException)
    {
    Thread.ResetAbort();
    }
      

  13.   


    namespace ThreadTemplate{
        using System;
        using System.Threading;
        using System.IO;    /// <summary>
        /// Summary description for clsSubThread.
        /// </summary>    public class clsSubThread:IDisposable    {        private Thread thdSubThread = null;
            private Mutex mUnique = new Mutex();
            private bool blnIsStopped;
            private bool blnSuspended;
            private bool blnStarted;
            private int nStartNum;        public bool IsStopped
            {
                get{ return blnIsStopped; }
            }        public bool IsSuspended
            {
                get{ return blnSuspended; }
            }        public int ReturnValue
            {
                get{ return nStartNum;}
            }        public clsSubThread( int StartNum )
            {
                blnIsStopped = true;
                blnSuspended = false;
                blnStarted = false;   
                nStartNum = StartNum;
            }        public void Start()
            {
                if( !blnStarted )
                {
                    thdSubThread = new Thread( new ThreadStart( SubThread ) );
                    blnIsStopped = false;
                    blnStarted = true;
                    thdSubThread.Start();
                }
            }         /// <summary>        /// Thread entry function        /// </summary>        private void SubThread()
            {
                try
                {
                do
                {
                // Wait for resume-command if got suspend-command here  
                    mUnique.WaitOne();   //这两个函数
                    mUnique.ReleaseMutex();//是必须的,,你可以在CSDN上查下
                    nStartNum++;       
                    Thread.Sleep(1000); // Release CPU here
                }while( blnIsStopped == false );
                }
                } 
                catch(ThreadAbortException abort_ex) { 
                //在外部调用Stop()方法,也就它调用thdSubThread.Abort();
           //该循环线程会终止抛出该异常。
                }
            }        public void Suspend()
            {
                if( blnStarted && !blnSuspended )
                {
                    blnSuspended = true;
                    mUnique.WaitOne();
                }
            }        public void Resume()
            {
                if( blnStarted && blnSuspended )
                {
                    blnSuspended = false;
                    mUnique.ReleaseMutex();
                }
            }        public void Stop()
            {
                if( blnStarted )
                {
                    if( blnSuspended )
                        Resume();
                    blnStarted = false;
                    blnIsStopped = true;
                    thdSubThread.Abort();
                }
            }
    使用开关变量。当在线程函数中,执行到“mUnique.WaitOne();”这一句的时候,如果此时外界没有发送Suspend消息,也就是信号量没有被占用,那么这一句可以立刻返回。那么为什么要紧接着释放呢,因为不能总占着信号量,立即释放信号量是避免在发送Suspend命令的时候出现等待;如果此时外界已经发送了Suspend消息,也就是说信号量已经被占用,此时“mUnique.WaitOne();”不能立刻返回,需要等到信号量被释放才能继续进行,也就是需要调用Resume的时候,“mUnique.WaitOne();”才能获得信号量进行继续执行。这样才能达到真正意义上的Suspend和Resume。此方法来源  Knight94 的博客。
    我就是用的他的方法实现的
      

  14.   

    什么意思?
    To:wyyq11:使用TerminateThread需要线程句柄参数,似乎无法获取Thread对象对应的线程句柄。
      

  15.   

    while (t.IsAlive)
    {
     try
     {
      t.Abort();
     }
     catch
     {
     }
    }

      

  16.   

    这个是在线程外执行!!
    t才是那个while(true)线程
      

  17.   


    人家的代码似乎没有用到TerminateThread函数,只是教给你一种重启,暂停线程的方法;
      

  18.   

    结贴:.net 2.0以上版本中无法终止执行该代码的线程,除非退出进程!