C# Thread.Abort()并在finally之后延迟
当调用Thread.Abort()时,该线程正在执行finally块,那么直到finally块完成,线程才会中止。但是,正如我所看到的,ThreadAbortException不是在finally块结束之后生成的,而是在经过一些延迟之后生成的:C# Thread.Abort()并在finally之后延迟,c#,multithreading,abort,finally,C#,Multithreading,Abort,Finally,当调用Thread.Abort()时,该线程正在执行finally块,那么直到finally块完成,线程才会中止。但是,正如我所看到的,ThreadAbortException不是在finally块结束之后生成的,而是在经过一些延迟之后生成的: private static volatile int val1 = 0; public static void Func1() { try { } finally { Thread.Sleep(
private static volatile int val1 = 0;
public static void Func1()
{
try
{
}
finally
{
Thread.Sleep(5000);
}
//Func2();
while (true)
val1++;
}
public static void Main()
{
var thread = new Thread(Func1);
thread.Start();
Thread.Sleep(1000);
thread.Abort();
thread.Join();
Console.WriteLine(val1); // val1 is non-zero!
}
在本例中,Main()末尾的val1将为非零。为什么会这样
如果我取消对Func2()的注释调用(Func2是任何方法,可能为空),则val1的输出将显示“0”。为什么添加方法会影响线程终止点?在这种情况下,可以使用
锁将增量包围起来。锁控制该成员的访问。Abort
方法只是通知线程“嘿,你现在可以停止了”,但它不会终止线程。因此,线程可以在中止后保持活动状态几分钟。访问锁
线程检查它是否被中止,并在需要时自行终止
下面是您的示例代码
使用系统;
使用系统线程;
名称空间控制台EAPP1
{
班级计划
{
私有静态volatile int val1=0;
静态对象锁定器=新对象();
公共静态void Func1()
{
尝试
{
}
最后
{
睡眠(5000);
}
//Func2();
while(true)
{
//锁定对成员的访问权限
锁(储物柜)
val1++;
}
}
公共静态void Main()
{
变量线程=新线程(Func1);
thread.Start();
睡眠(1000);
//不需要,只是为了确定一下
锁(储物柜)
{
thread.Abort();
thread.Join();
}
Console.WriteLine(val1);//val1不是零!
//现在是零
Console.ReadLine();
}
}
}
很抱歉回答得太晚了有趣的问题,但是在没有附加调试器的发布模式下,我可以为val1
也Func2()
获取一个非零的数字,并使用空函数取消注释。如果在发行版中附加了调试器,或者在调试中使用我们的调试器,而没有调试器,则都会给我0。Thread.Abort
很糟糕,非常糟糕。它将使您的应用程序处于不可预测的状态,并且在使用它之后,您将无法依赖关于程序行为的常见假设。您应该不惜一切代价调用它。<代码>线程。异常终止>代码>可以在锁定区域的中间中止线程。如果发生这种情况,它将不会释放锁。这是一个非常危险的建议。它会释放锁,因为锁的释放在finally块中是内部的,如果线程在finally的某个情况下中止,finally块将始终执行,因为线程实际上会因为ThreadAbortException而被killed。您也可以只处理该异常。检查这并不总是正确的。如果线程在finally块期间中止,它可以跳过释放锁。请看和一些实际设计C#和.NET的人的讨论。