Как я могу настроить обработку .NET UnhandledException в службе Windows?
protected override void OnStart(string[] args)
{
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Thread.Sleep(10000);
throw new Exception();
}
void CurrentDomain_UnhandledException(object sender,
UnhandledExceptionEventArgs e)
{
}
Я подключил отладчик к указанному выше коду в моей службе Windows, установив точку останова в CurrentDomain_UnhandledException, но он никогда не попадал. Исключение появляется, говоря, что он необработан, а затем служба останавливается. Я даже попытался поместить некоторый код в обработчик события, если он был оптимизирован.
Неправильно ли вы настроили обработку необработанных исключений в службе Windows?
Ответы
Ответ 1
Я пришел к этой теме довольно поздно, но я подумал, что может быть полезно дать объяснение, которое не дает ни один из других ответов.
Причина, по которой обработчик CurrentDomain_UnhandledException
не попадает в образец кода OP, заключается в том, что метод OnStart
вызывается в ответ на команду "Пуск" из диспетчера управления службами Windows (команда получена и отправлена этому методу в рамках реализации ServiceBase Framework); любое исключение, которое выбрано OnStart
, обрабатывается в базовом классе, регистрируется в журнале событий и преобразуется в код состояния ошибки, возвращаемый в SCM. Таким образом, исключение никогда не распространяется на обработчик необработанных исключений AppDomain.
Думаю, вы обнаружите, что обработанное CurrentDomain_UnhandledException
обработано необработанным исключением из рабочего потока в вашей службе будет.
Ответ 2
В службе Windows вы не хотите запускать много кода в методе OnStart. Все, что вам нужно, - это код для запуска потока обслуживания и возврата.
Если вы это сделаете, вы можете обрабатывать исключения, которые происходят в вашем потоке обслуживания, только отлично.
например.
public static void Start()
{
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(currentDomain_UnhandledException);
running = true;
ThreadStart ts = new ThreadStart(ServiceThreadBody);
thread = new Thread(ts);
thread.Name = "ServiceThread";
thread.Priority = ThreadPriority.BelowNormal;
thread.Start();
}
Ответ 3
Знайте, что этот поток немного устарел, но подумал, что было бы полезно добавить некоторые комментарии на основе личного опыта разработки служб Windows в .NET. Лучший подход - избегать разработки в Менеджере управления службами, насколько это возможно. Для этого вам понадобится простая проводка, которая имитирует способ запуска служб - что-то, что может создайте экземпляр своего класса обслуживания (который уже выведен из ServiceBase) и вызовите методы OnStart, OnStop и т.д. Этот жгут может быть консольным приложением или приложением Windows по вашему желанию.
Это в значительной степени единственный способ найти проблемы с запуском службы отладки в .NET - взаимодействие между вашим кодом, Visual Studio и реальным диспетчером управления сервисами просто делает процесс невозможным иначе.
НТН.
Ответ 4
Просто любопытно, что вы пытаетесь выполнить: избегая сбоев в обслуживании или сообщений об ошибках?
Для отчетности я считаю, что ваш лучший выбор - добавить заявления на высший уровень try/catch. Вы можете попытаться зарегистрировать их в журнале событий Windows и/или в файле журнала.
Вы также можете установить свойство ExitCode на ненулевое значение, пока вы не остановите службу. Если системный администратор запустит вашу службу с панели управления "Службы", и ваша служба внезапно остановится с ненулевым кодом выхода, Windows может показать сообщение об ошибке с описанием ошибки.
Ответ 5
Когда я работал над своей собственной службой Windows, она останавливалась сама по себе довольно странно. Я думал, что это из-за неподготовленного исключения. На данный момент я нахожусь в непонятных исключениях из текстового файла. Прежде всего, вам нужно создать новый файл ServiceLog.txt на местах C из-за регистрации подделок в текстовом файле. С нижеследующим кодированием я получил все без исключения исключения с номерами строк.
using System.Security.Permissions;
using System.IO;
[SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)]
protected override void OnStart(string[] args)
{ AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyHandler);
...
Your codes...
....
}
void MyHandler(object sender, UnhandledExceptionEventArgs args)
{
Exception e = (Exception)args.ExceptionObject;
WriteToFile("Simple Service Error on: {0} " + e.Message + e.StackTrace);
}
private void WriteToFile(string text)
{
string path = "C:\\ServiceLog.txt";
using (StreamWriter writer = new StreamWriter(path, true))
{
writer.WriteLine(string.Format(text, DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss tt")));
writer.Close();
}
}