Доброе утро,
Здесь немного вопроса теории языка... Я нашел в Интернете несколько ссылок, предполагающих, что обработка исключений и делегаты в С# в некоторых случаях ведут себя по-разному, но я не могу найти никакой конкретной документации по этому вопросу.
Недавно у нас были большие проблемы с исключениями внутри делегатов для надстройки Microsoft Excel, что приводило к жесткому сбою в среде выполнения MSVC. Удаление делегатов решило эту проблему, но теперь мне любопытно узнать кровавые подробности.
В качестве краткого примера основного кода:
Delegate del; // initialized elsewhere
try
{
del.DynamicInvoke();
}
catch(Exception e)
{
/* Parsing of exception to generate user-friendly message here */
}
Приведенная выше конструкция допускала централизованную форму обработки ошибок и с точки зрения чистого кода была чистой и лаконичной. Каждая общедоступная функция была объявлена как делегат и выполнялась через приведенный выше фрагмент.
В простом консольном приложении исключение из делегата или просто неожиданная ошибка (например, «случайный» вызов ToString() для нулевого указателя) работает, как и ожидалось, и ошибка обрабатывается по желанию.
Добавьте MS Excel, и вы получите хард-краши. Пошаговое выполнение кода покажет, где возникает ошибка, но никакого раскручивания стека, по-видимому, не происходит, прежде чем все рухнет в большом огненном шаре разрушения.
Моя гипотеза состоит в том, что COM, на котором размещена среда выполнения .NET (и, следовательно, наш код), делает что-то отличное от обычного выполнения кода .NET. Это убивает конечную точку, и Excel не знает об этом, который, в свою очередь, пытается получить доступ к конечной точке через COM только для того, чтобы обнаружить, что она каким-то образом исчезла, и Excel в ответ вылетает.
Это происходит только с комбинацией делегатов Excel+COM+, но я, честно говоря, не знаю, что больше влияет на это поведение... есть мысли?