Есть ли в .NET исключение, аналогичное EAbort в Delphi? - PullRequest
3 голосов
/ 30 июля 2009

Есть ли в .NET исключение, аналогичное EAbort в Delphi?

В настоящее время я определяю свой собственный «AbortProcess», наследующий исключение. Вместе с My.Application.UnhandledException обработчик, который игнорирует «AbortProcess» Мне все еще интересно, существует ли подобный механизм в .NET.

Class AbortProcess
    Inherits System.Exception
End Class

Sub Abort()
    Throw New AbortProcess()
End Sub

Sub AppDomain_UnhandledException(ByVal sender As Object, ByVal e As ApplicationServices.UnhandledExceptionEventArgs)
    If TypeOf e.Exception Is AbortProcess Then
        e.ExitApplication = False
    End If
End Sub    

Sub PerformActions()
    Action1()
    If Not Action2() Then
        Abort()
    End If
    Action3()
    ...
End Sub

Как типичный разработчик .NET справляется с этим вариантом использования?

ОБНОВЛЕНИЕ:

По ряду причин, к сожалению, некоторые люди проголосовали за этот вопрос, но не дали никаких комментариев. Единственная причина, по которой я могу понять, заключается в том, что они могут полагать, что Исключение никогда не следует использовать для управления потоком программ; и я склонен с этим согласиться. Однако недавно я изучил ANTLR и обнаружил, что они действительно используют пользовательское исключение (RecognitionException) в качестве конструкции потока управления. Я полагаю, что вместе с использованием StopItate в Python использование Exception в качестве конструкции потока управления уже широко используется. Это просто не стандартизировать, как в Delphi VCL.

Ответы [ 4 ]

5 голосов
/ 30 июля 2009

Есть два качества, которые определяют класс исключений Delphi EAbort.

  1. Среда IDE предварительно настроена для , а не прерывания вашей программы, когда она обнаруживает исключение для этого класса.
  2. Основной обработчик исключений приложения распознает EAbort и его потомков и не отображает обычное окно сообщения при обнаружении такого исключения.

Похоже, что предложенный вами код завершает вторую часть. Вы можете настроить Visual Studio для первой части; обратитесь к ответу на другой вопрос переполнения стека, Есть ли лучший способ заставить Visual Studio игнорировать try / catch в режиме отладки? Я не знаю ни одного класса исключений, уже предназначенного для этого.

Исключение EAbort предназначено для того, чтобы программа перестала запускать какой-либо обработчик событий или сообщений и продолжала работу в главном цикле сообщений. Однако, чтобы это действительно работало, весь ваш другой код должен быть написан для правильной обработки исключений. То есть им нужно использовать секции finally, чтобы поддерживать себя в стабильных и согласованных состояниях, и им необходимо либо перебрасывать, либо никогда не перехватывать исключения, которые они на самом деле не способны исправить.

0 голосов
/ 30 июля 2009

Если вы хотите быстро выйти из приложения в .Net, исключение - не лучший путь. Любое исключение, которое вы явно выбрасываете, может быть поймано и проглочено. Даже опасные исключения, такие как ThreadAbortException, могут быть обнаружены, если вы сделаете правильные трюки.

Лучший способ быстро выйти из приложения - использовать Environment.Exit.

Это или намеренное создание сценария переполнения стека, так как это неуловимое исключение, когда оно генерируется CLR (не предоставляя пользовательский хост).

0 голосов
/ 30 июля 2009

Это, по сути, исключение, которое просто служит для быстрого выхода из функции. Исключения .NET не предназначены для этого, и их проглатывание - довольно плохая практика.

Исключения не должны использоваться для обработки потока данных. Если вы думаете, что что-то может потерпеть неудачу, вы можете выбросить исключение, но затем поймать это в первый подходящий момент. Допускать попадание исключения в функцию UnhandledException и его проглатывание - это просто плохая практика, которая может оставить ваше приложение в неизвестном состоянии (поскольку все методы, через которые проходит исключение, будут «прерваны»).

В этом случае, если вам нужно исключение в этом сабе, я бы поймал его при вызове:

try {
    PerformActions()
} catch (AbortProcess) {
    //do some cleaning up or just ignore
}

Таким образом, исключение обнаруживается близко к его источнику, и любая очистка ограничивается только этой функцией. Все остальные исключения будут переданы вашей функции UnhandledException, где лучшее, что вы можете сделать, - сообщить об ошибке и закрыть приложение.

0 голосов
/ 30 июля 2009

Единственное, что я знаю, это ThreadAbortException , что означает "" Исключение, которое выдается при вызове метода Abort."

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...