当前位置:编程学习 > C#/ASP.NET >>

try-catch-finally 引发的奇怪问题

今天,发现我们的一个Windows Service无易做图常停止,无奈之下只能杀了进程。
 
为了找到原因,我在本地进行调试,发现程序里用到了多线程,而代码正是卡在了workThread.Abort()语句而无法停止。
 
为什么不能Abort? 继续看线程调用的方法的代码,发现没有什么特殊的代码,只是在其中用了Thread.Sleep进行长时间等待。
 
难道是这个引起的? 写了一个测试程序验证,
 
 
class Program  
    {  
        private readonly Thread workThread;  
  
        public Program()  
        {  
            workThread = new Thread(DoWork);  
        }  
  
        static void Main(string[] args)  
        {  
            new Program().Work();  
            Console.ReadLine();  
        }  
  
        private void Work()  
        {  
            workThread.Start();  
            Thread.Sleep(1 * 1000);  
  
            Console.WriteLine("aborting");  
            workThread.Abort();  
            Console.WriteLine("aborted");  
        }  
  
        private void DoWork()  
        {  
                Console.WriteLine("started");  
               Thread.Sleep(300 * 1000);  
        }  
    }  
发现可以正常终止。

started
aborting
aborted


再仔细检查,发现其中一处Thread.Sleep放在了finally块中,修改测试代码

class Program
    {
        private readonly Thread workThread;

        public Program()
        {
            workThread = new Thread(DoWork);
        }

        static void Main(string[] args)
        {
            new Program().Work();
            Console.ReadLine();
        }

        private void Work()
        {
            workThread.Start();
            Thread.Sleep(1 * 1000);
            Console.WriteLine("aborting");
            workThread.Abort();

            Console.WriteLine("aborted");
        }

        private void DoWork()
        {
            try
            {
                Console.WriteLine("started");
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                for (int i = 0; i < 3; i++)
                {
                    Console.WriteLine("ThreadState:" + workThread.ThreadState);
                    Thread.Sleep(1000);
                }
            }
        }
    }

 

 
输出:
 
started
ThreadState:Running
aborting
ThreadState:AbortRequested
ThreadState:AbortRequested
aborted
MSDN是这样解释的:
 
线程不一定会立即中止,或者根本不中止。 如果线程在作为中止过程的一部分被调用的 finally 块中做非常大量的计算,从而无限期延迟中止操作,则会发生这种情况。
 
http://msdn.microsoft.com/zh-cn/library/5b50fdsz.aspx
其实追根溯源,问题是出在程序员对try-catch-finally的滥用上,finally块应该是用来做一些收尾工作,而不是等待操作。
 
finally 块用于清除 try 块中分配的任何资源,以及运行任何即使在发生异常时也必须执行的代码。
 
http://msdn.microsoft.com/zh-cn/library/zwc8s4fz%28v=vs.80%29.aspx
 
 
找到了原因,解决方案也挺简单,将Thread.Sleep从finally块中移除即可。
 
 
补充:软件开发 , C# ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,