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

今天,发现我们的一个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.Sleepfinally块中移除即可

 

 

本文链接:http://www.cnblogs.com/feiyun0112/p/3347087.html,转载请注明。



You must enable javascript to see captcha here!

Copyright © All Rights Reserved · Green Hope Theme by Sivan & schiy · Proudly powered by WordPress

无觅相关文章插件,快速提升流量