c# - servicios - ¿Cómo puedo configurar el manejo de.NET UnhandledException en un servicio de Windows?
servicios windows c# (5)
Cuando estaba trabajando en mi propio Servicio de Windows, se estaba deteniendo de forma bastante extraña. Pensé que era por una excepción sin manos. Por el momento estoy atrapando excepciones sin manos en el archivo de texto. En primer lugar, debe crear el nuevo archivo ServiceLog.txt en las ubicaciones C debido a las anotaciones de registro en el archivo de texto. Con la codificación de abajo obtuve todas las excepciones sin mano con ellos los números de línea.
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();
}
}
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)
{
}
Adjunté un depurador al código anterior en mi servicio de Windows, estableciendo un punto de interrupción en CurrentDomain_UnhandledException, pero nunca fue afectado. La excepción aparece diciendo que no se ha manejado, y luego el servicio se detiene. Incluso traté de poner algún código en el controlador de eventos, en caso de que se optimizara.
¿No es esta la forma correcta de configurar el control de excepciones no controladas en un servicio de Windows?
En un servicio de Windows, NO desea ejecutar muchos códigos en el método OnStart. Todo lo que desea es el código para iniciar su cadena de servicio y luego regresar.
Si lo hace, puede manejar las excepciones que suceden en su cadena de servicio sin problemas.
p.ej
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();
}
He llegado a este hilo bastante tarde, pero pensé que podría valer la pena dar una explicación que ninguna de las otras respuestas da.
El motivo por el que el controlador CurrentDomain_UnhandledException
no se muestra en el código del OP es que se OnStart
método OnStart
en respuesta a un comando de Inicio del Administrador de control de servicios de Windows (el comando se recibe y se envía a este método mediante la implementación de ServiceBase del marco); cualquier excepción lanzada por OnStart
se maneja en la clase base, se registra en el registro de eventos y se traduce en un código de estado de error devuelto al SCM. Entonces la excepción nunca se propaga al controlador de excepción no controlada de AppDomain.
Creo que encontrará que el controlador CurrentDomain_UnhandledException
atrapará una excepción no controlada lanzada desde un subproceso de trabajador en su servicio.
Sepa que este hilo es un poco viejo, pero pensó que sería útil agregar algunos comentarios basados en la experiencia personal de desarrollo de servicios de Windows en .NET. El mejor enfoque es evitar el desarrollo bajo el Administrador de control de servicios tanto como pueda ; para esto necesita un arnés simple que imita la forma en que se inician los servicios, algo que puede crear una instancia de su clase de servicio (que ya ha derivado de ServiceBase ) y llame a sus métodos OnStart, OnStop, etc. Este arnés puede ser una aplicación de consola o una aplicación de Windows como lo desee.
Esta es prácticamente la única forma que he encontrado de depurar los problemas de arranque del servicio en .NET: la interacción entre su código, Visual Studio y el Administrador de control de servicio real simplemente hace que el proceso sea imposible de lo contrario.
HTH.
Solo curiosidad, ¿qué intentas lograr: evitar fallar el servicio o informar errores?
Para informar, creo que su mejor opción es agregar declaraciones try / catch de nivel superior. Puede tratar de registrarlos en el registro de eventos de Windows y / o en un archivo de registro.
También puede establecer la propiedad ExitCode en un valor distinto de cero hasta que ExitCode exitosamente el servicio. Si el administrador del sistema inicia su servicio desde el panel de control de Servicios, y su servicio se detiene repentinamente con un código de salida distinto de cero, Windows puede mostrar un mensaje de error con la descripción del error.