Наконец блок, всегда выполняемый?

Отмена в .Net является совместной.

Это означает, что тот, у кого есть отмена сигналов CancellationTokenSource, и тот, у кого есть CancellationToken, должен проверить, была ли отменена сигнализация (либо путем опроса CancellationToken или путем регистрации делегата для запуска при его сигнале).

В вашем Task.Run вы используете параметр CancellationToken в качестве параметра, но вы не проверяете его внутри самой задачи, поэтому

Чтобы отменить задачу во время ее выполнения, вам нужно проверить CancellationToken:

var task = Task.Run(() =>
{
    token.ThrowIfCancellationRequested();
}, token);

В вашем случае вы блокируете ManualResetEvent, чтобы вы не смогли проверить CancellationToken. Вы можете зарегистрировать делегата в CancellationToken, который освобождает событие сброса:

token.Register(() => waitHandle.Set())
110
задан Michael Myers 21 January 2009 в 05:03
поделиться

6 ответов

от Учебные руководства Sun

Примечание: Если JVM выходит, в то время как код попытки или выгоды выполняется, то наконец блок не может выполниться. Аналогично, если поток, выполняющий попытку или код выгоды, прерван или уничтожен, наконец, блок не может выполниться даже при том, что приложение в целом продолжается.

я не знаю ни о каких других путях наконец, блок не выполнился бы...

136
ответ дан mt0321 5 November 2019 в 09:59
поделиться

System.exit закрывает Виртуальную машину.

Завершает в настоящее время рабочую виртуальную машину Java. Аргумент служит кодом статуса; условно, ненулевой код статуса указывает на аварийное завершение.

Это вызовы метода exit метод в классе Runtime. Этот метод никогда не возвращается обычно.

    try {
        System.out.println("hello");
        System.exit(0);
    }
    finally {
        System.out.println("bye");
    } // try-finally

"до свидания" не распечатывает в вышеупомянутом коде.

62
ответ дан Eugene Yokota 5 November 2019 в 09:59
поделиться
try { for (;;); } finally { System.err.println("?"); }

В этом случае наконец не выполнится (если устаревшее Thread.stop не называют, или эквивалент, скажем, через интерфейс инструментов).

10
ответ дан Tom Hawtin - tackline 5 November 2019 в 09:59
поделиться

Только, чтобы подробно остановиться, что сказали другие, что-либо, что не вызывает что-то как выход JVM, подвергнется наконец блок. Так следующий метод:

public static int Stupid() {
  try {
    return 0;
  }
  finally {
    return 1;
  }
}

странно оба скомпилирует и возвратится 1.

49
ответ дан Daniel Nadasi 5 November 2019 в 09:59
поделиться

Связанный с System.exit, существуют также определенные типы катастрофического отказа, где наконец блок не может выполниться. Если JVM исчерпывает память полностью, это может просто выйти без выгоды или наконец случая.

А именно, я помню проект, где мы по-дурацки пытались использовать

catch (OutOfMemoryError oome) {
    // do stuff
}

, Это не работало, потому что JVM не имела никакой памяти, уехал в выполнение блока выгоды.

15
ответ дан Zarkonnen 5 November 2019 в 09:59
поделиться

Учебник Sun неправильно цитируется здесь в этой ветке.

Примечание. Если JVM завершает работу во время выполнения кода try или catch, то блок finally не будет выполняться . Аналогично, если поток, выполняющий код попытки или улова, прерывается или завершается, блок finally не будет выполняться, даже если приложение в целом продолжает работу.

Если вы внимательно посмотрите на руководство Sun для блока finally, в нем не говорится «не будет выполняться», но «может не выполняться» Вот правильное описание

Примечание: если JVM завершает работу, пока выполняется код попытки или отлова, затем блок finally может не выполняться. Аналогично, если поток, выполняющий код попытки или улова, прерывается или завершается, блок finally может не выполняться, даже если приложение в целом продолжает работу.

Очевидная причина такого поведения заключается в том, что вызов system.exit () обрабатывается в системном потоке времени выполнения, что может занять время для завершения работы jvm, в то время как планировщик потоков может наконец запросить выполнение. Итак, finally разработан так, чтобы всегда выполняться, но если вы закрываете jvm, может случиться так, что jvm отключится до того, как, наконец, будет запущен.

8
ответ дан 24 November 2019 в 03:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: