Основываясь на своих исследованиях, я узнал следующее:
TaskScheduler.UnobservedTaskException
должен дождаться, пока задача будет собрана сборщиком мусора, прежде чем ненаблюдаемое исключение этой задачи будет всплыть до события UnobservedTaskException
. - Если вы используете
Task.Wait()
, он все равно никогда не будет вызван, потому что вы блокируете ожидаемый результат от Задачи, следовательно, исключение будет выдано Task.Wait()
, а не всплытьна событие UnobservedException
. - Вызов
GC.Collect()
вручную, как правило, плохая идея, если вы точно не знаете, что делаете, поэтому в данном случае это хорошо для подтверждения вещей, но не как правильное решение дляпроблема.
Проблема
Если мое приложение завершит работу до того, как начнет работать сборщик мусора, я абсолютно на 100% не смогу запустить событие UnobservedTaskException
.
Обратите внимание на следующий код:
class Program
{
static void Main(string[] args)
{
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
Task.Factory.StartNew(() =>
{
Console.WriteLine("Task started.");
throw new Exception("Test Exception");
});
Thread.Sleep(1000);
//GC.Collect();
//GC.WaitForPendingFinalizers();
}
static void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
{
File.WriteAllText(@"C:\data\TestException.txt", e.Exception.ToString());
Console.WriteLine("UNOBSERVED EXCEPTION");
}
}
Файл исключений не записывается и ничего не записывается в консоль.После выхода из приложения может пройти 10-15 минут и более, и все же я не вижу доказательств того, что останки моего приложения были собраны мусором.Вы можете спросить, ну почему бы просто не собрать при выходе?Что ж, мой реальный сценарий таков, что моя ловушка исключений запускается внутри службы WCF, размещенной внутри службы Windows.Я не могу перехватить, когда служба Windows завершает работу (и, следовательно, вручную вызывает GC.Collect()
), потому что, насколько я вижу, для этого нет события.
Куда я иду не так?Как я могу гарантировать, что если что-то глубоко внутри службы WCF в конечном итоге сломает мою службу Windows, у меня будет шанс зарегистрировать исключение до того, как служба перестанет работать?