try-catch-finally 引发的奇怪问题
2013-09-30 22:27
211 查看
今天,发现我们的一个Windows Service无法正常停止,无奈之下只能杀了进程。
为了找到原因,我在本地进行调试,发现程序里用到了多线程,而代码正是卡在了workThread.Abort()语句而无法停止。
为什么不能Abort? 继续看线程调用的方法的代码,发现没有什么特殊的代码,只是在其中用了Thread.Sleep进行长时间等待。
难道是这个引起的? 写了一个测试程序验证,
发现可以正常终止。
再仔细检查,发现其中一处Thread.Sleep放在了finally块中,修改测试代码
输出:
MSDN是这样解释的:
其实追根溯源,问题是出在程序员对try-catch-finally的滥用上,finally块应该是用来做一些收尾工作,而不是等待操作。
找到了原因,解决方案也挺简单,将Thread.Sleep从finally块中移除即可。
为了找到原因,我在本地进行调试,发现程序里用到了多线程,而代码正是卡在了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块中移除即可。
相关文章推荐
- try-catch-finally 引发的奇怪问题
- try-catch-finally 引发的奇怪问题
- try-catch-finally 引发的奇怪问题
- Java面试题-关于try...catch...finally中的问题
- 逐行读txt文件(读写文件try catch finally 处理空行,编码格式,文件流释放问题,处理读到重复问题)
- 黑马程序员 try或catch中存在return 语句时,它们与finally 的执行顺序问题
- try catch finally 与 return 的问题
- try{}catch{}finally{}的逻辑错误问题
- java中try{}catch{}和finally{}的执行顺序问题
- try catch finally中return语句与非return语句的执行顺序问题
- Java中的try+catch+finally+return的返回值问题
- java中try{}catch{}和finally{}的执行顺序问题
- java try catch finally中的return问题
- try-catch-finally执行与返回值问题
- try catch finally 返回值问题
- 解决try catch finally中close的问题
- 在try,catch,finally中return,throw覆盖的问题总结
- 从JVM指令层面看try-catch-finally返回值问题
- 转载 try ..catch ..finally 执行问题
- 【Java】try、catch、finally的执行顺序与返回值问题