У меня забавная проблема, когда во время закрытия приложения блоки try / catch в стеке, похоже, игнорируются.
У меня нет работающего тестового проекта (но из-за крайнего срока, в противном случае я бы полностью попытался повторить это), но рассмотрим следующий фрагмент кода.
class IndexNotFoundException : Exception { }
public static string RunAndPossiblyThrow(int index, bool doThrow)
{
try
{
return Run(index);
}
catch(IndexNotFoundException e)
{
if(doThrow)
throw;
}
return "";
}
public static string Run(int index)
{
if(_store.Contains(index))
return _store[index];
throw new IndexNotFoundException ();
}
public static string RunAndIgnoreThrow(int index)
{
try
{
return Run(index);
}
catch(IndexNotFoundException e)
{
}
return "";
}
Во время выполнения этот шаблон отлично работает. Мы получаем унаследованную поддержку кода, который использует исключения для управления программой (плохо), и мы можем двигаться вперед и медленно удалять исключения, используемые для управления программой.
Однако при закрытии нашего пользовательского интерфейса мы видим исключение, выдаваемое из «Run», даже если «doThrow» имеет значение false для ВСЕХ текущих применений «RunAndPossblyThrow». Я даже зашел так далеко, чтобы проверить это, изменив код так, чтобы он выглядел как «RunAndIgnoreThrow», и я все равно получу аварийное завершение работы после отключения пользовательского интерфейса.
г. Эрик Липперт, я читаю ваш блог ежедневно, я бы с радостью узнал, что это какая-то известная ошибка, и я не схожу с ума.
EDIT
Это многопоточный, и я убедился, что все объекты не были изменены при доступе
EDIT
Явное шоу исключение наше
EDIT
забыл упомянуть, это на закрытии, и, к сожалению, Visual Studio не может поймать падение непосредственно. Скорее всего, происходит сбой в потоке, отличном от потока пользовательского интерфейса, и после закрытия основного происходит закрытие. Я смог отладить это только путем многократного запуска и закрытия приложения с открытым диспетчером задач «Создать файл дампа» и просмотром полученного беспорядка в 400+ мегабайт в Windbg. Win7 64 для справки. Убедитесь, что это имеет смысл для вас.
EDIT
Следующий код при завершении работы по-прежнему показывает то же исключение.
class IndexNotFoundException : Exception { }
public static string RunAndPossiblyThrow(int index, bool doThrow)
{
try
{
return Run(index);
}
catch
{
}
return "";
}
public static string Run(int index)
{
if(_store.Contains(index))
return _store[index];
throw new IndexNotFoundException ();
}
Единственное, что, кажется, избавляется от исключения, - это перейти прямо к
class IndexNotFoundException : Exception { }
public static string RunAndPossiblyThrow(int index, bool doThrow)
{
try
{
return Run(index);
}
catch
{
}
return "";
}
public static string Run(int index)
{
if(_store.Contains(index))
return _store[index];
return "";
}
Естественно, исключение прошло, но мои страхи сойти с ума все еще присутствуют.
EDIT
стало еще хуже ... это все еще падает ...
class IndexNotFoundException : Exception { }
public static string RunAndPossiblyThrow(int index, bool doThrow)
{
try
{
throw new IndexNotFoundException();
}
catch
{
}
return "";
}
EDIT
У меня есть отчетливое чувство, что это никуда меня не приведет. Помимо странного поведения, я также могу заметить, что во время выполнения пользовательского интерфейса в вышеупомянутом случае try catch выполняется точно. Мой пользовательский интерфейс не падает, и он полон пустых строк. Однако, как только я начинаю закрывать пользовательский интерфейс, происходит сбой, и попытка перехвата больше не сдерживает исключение.
РЕДАКТИРОВАТЬ и окончательный
По-видимому, файл дампа содержал в нем самое последнее исключение первого шанса. Я проверил это, создав новый проект, который бросил внутрь и поймал 10 секунд. Во время ожидания я получил файл .dmp и, конечно же, обнаружилось мое полностью перехваченное исключение.
Я отмечу несколько баллов за полезные ответы, однако, к сожалению, до сих пор нет ни рифмы, ни причины, по которой мой код падает ...