В коде С# вы можете поймать собственное исключение, которое было выведено из глубины в некоторая неуправляемая библиотека? Если это так, вам нужно сделать что-то по-другому, чтобы поймать его или сделать стандартную попытку... поймать его?
Можете ли вы поймать собственное исключение в коде С#?
Ответ 1
Вы можете использовать Win32Exception и использовать его свойство NativeErrorCode для правильной обработки.
// http://support.microsoft.com/kb/186550
const int ERROR_FILE_NOT_FOUND = 2;
const int ERROR_ACCESS_DENIED = 5;
const int ERROR_NO_APP_ASSOCIATED = 1155;
void OpenFile(string filePath)
{
Process process = new Process();
try
{
// Calls native application registered for the file type
// This may throw native exception
process.StartInfo.FileName = filePath;
process.StartInfo.Verb = "Open";
process.StartInfo.CreateNoWindow = true;
process.Start();
}
catch (Win32Exception e)
{
if (e.NativeErrorCode == ERROR_FILE_NOT_FOUND ||
e.NativeErrorCode == ERROR_ACCESS_DENIED ||
e.NativeErrorCode == ERROR_NO_APP_ASSOCIATED)
{
MessageBox.Show(this, e.Message, "Error",
MessageBoxButtons.OK,
MessageBoxIcon.Exclamation);
}
}
}
Ответ 2
Catch without() будет захватывать исключения, не совместимые с CLS, включая собственные исключения.
try
{
}
catch
{
}
Для получения дополнительной информации см. следующее правило FxCop http://msdn.microsoft.com/en-gb/bb264489.aspx
Ответ 3
Уровень взаимодействия между С# и собственным кодом преобразует исключение в управляемую форму, позволяя ему быть пойманным вашим кодом С#. Начиная с .NET 2.0, catch (Exception)
должен улавливать что-либо, кроме неустранимой ошибки.
Ответ 4
Где-то с использованием .NET Reflector я видел следующий код:
try {
...
} catch(Exception e) {
...
} catch {
...
}
Hmm, С# не позволяет исключать исключение из класса System.Exception. И насколько я знаю какое-либо исключение, cautch от interch marshaller завершается классом исключений, который наследует System.Exception.
Итак, мой вопрос в том, можно ли поймать исключение, которое не является исключением System.Exception.
Ответ 5
Это зависит от того, в каком типе родного исключения вы говорите. Если вы ссылаетесь на исключение SEH, CLR будет делать одну из двух вещей.
- В случае известного кода ошибки SEH он сопоставляет его с соответствующим исключением .NET(т.е. OutOfMemoryException)
- В случае несовместимого (E_FAIL) или неизвестного кода он просто выкинет экземпляр SEHException.
Оба из них будут пойманы с помощью простого блока catch (Exception).
Другим типом родного исключения, которое может пересекать собственную/управляемую границу, являются исключения С++. Я не уверен, как они отображаются/обрабатываются. Я предполагаю, что, поскольку Windows реализует исключения С++ поверх SEH, они просто отображаются одинаково.
Ответ 6
Почти, но не совсем. Вы поймаете исключение с помощью
try
{
...
}
catch (Exception e)
{
...
}
но у вас все еще будут проблемы. Согласно MSDN, чтобы обеспечить исключение, вызываемые деструкторы вызываются, вам придется поймать, например:
try
{
...
}
catch
{
...
}
Это единственный способ гарантировать, что вызван деструктор исключения (хотя я не уверен, почему). Но это оставляет вам компромисс между грубой силой и возможной утечкой памяти.
Кстати, если вы используете подход (Exception e), вы должны знать разные типы исключений, которые могут возникнуть. RuntimeWrappedException - это то, к чему будет управляться любой управляемый тип без исключения (для языков, которые могут вызывать строку), а другие будут отображаться, например OutOfMemoryException и AccessViolationException. COM Interop HRESULTS или исключения, отличные от E___FAIL, будут отображаться в COMException, и, наконец, в конце вы получите SEHException для E_FAIL или любое другое неотображенное исключение.
Так что вы должны делать? Лучший выбор - это не исключать исключения из вашего неуправляемого кода! Хах. На самом деле, хотя, если у вас есть выбор, возникают барьеры и неудачи, которые делают выбор, который хуже, вероятность утечки памяти во время обработки исключений или незнание того, какой тип является вашим исключением.
Ответ 7
Если вы используете
try
{
}
catch(Exception ex)
{
}
он будет перехватывать ВСЕ исключения, в зависимости от того, как вы вызываете внешние библиотеки, вы можете получить исключение, связанное с комком, которое инкапсулирует ошибку, но оно поймает ошибку.
Ответ 8
Стандартный try catch должен делать трюк, которому я верю.
У меня возникает аналогичная проблема с исключением System.data, бросающим исключение sqlClient, которое было неотобрано, добавив try..catch в мой код, сделал трюк в экземпляре