Все, что я прочитал, утверждает, что прерывание в потоке выполнит блок finally до окончания исключения ThreadAbortException. Я хотел подтвердить это, поэтому я могу планировать, как обращаться с некоторым сторонним кодом, который может вешать бесконечно. Однако следующий тест меня путать:Может ли ThreadAbortException пропустить наконец?
public void runTest(DateTime deadline)
{
testThread = new Thread(() =>
{
try
{
Console.WriteLine("test thread started at " + DateTime.Now.ToShortTimeString());
while (true) { }
}
finally
{
Console.WriteLine("test thread entered FINALLY at " + DateTime.Now.ToShortTimeString());
while (true) { }
}
});
testThread.Start();
while (testThread.IsAlive && deadline.Subtract(DateTime.Now).TotalSeconds > 0)
{
Console.WriteLine("main thread while loop " + DateTime.Now.ToShortTimeString());
Thread.Sleep(10000);
}
if (testThread.IsAlive)
testThread.Abort();
Console.WriteLine("main thread after abort call " + DateTime.Now.ToShortTimeString());
}
Что я нахожу при запуске в том, что консоль никогда не упоминает о входе окончательно заблокировать. Приложение продолжается после вызова .Bort, как будто никакого окончательного блока вообще нет. Я делаю что-то неправильно? Не следует ли переходить к блоку finally до того, как он достигнет окончательной записи на консоль, или же порядок выполнения все еще является функцией того факта, что, наконец, в отдельном потоке или что-то еще?
Я запустил код, и я получил «тестовый поток, введенный ПОЛНОСТЬЮ в 3:21 PM». – Romoku
Не пробовал, но я подозреваю, что код будет вести себя по-разному между отладчиками Debug и release/без отладчика, как бесконечный цикл, который, вероятно, будет JITed во что-то, что не может быть прервано в сборке релизов. –
Вызов 'Thread.Abort' - это как остановка автомобиля, снимая водителя в голове. Машина остановится, но пока не известно, что может произойти за это время. Вы действительно не должны * когда-либо * называть 'Thread.Abort'. Если да, то вам нужно пересмотреть дизайн вашего приложения. –