Pregunta

Estoy usando el TPL ( tarea paralela Biblioteca ) en .NET 4.0. Quiero centralizar la lógica de manejo de todas las excepciones no controladas mediante el evento Thread.GetDomain().UnhandledException. Sin embargo, en mi solicitud, el evento nunca es despedido por las discusiones iniciadas con el código de TPL, por ejemplo, Task.Factory.StartNew(...). El evento está hecho despedido si uso algo así como new Thread(threadStart).Start().

Este artículo de MSDN sugiere utilizar Task.Wait () para coger el AggregateException cuando se trabaja con TPL, pero eso no es lo que quiero porque este mecanismo no está "centralizada" suficiente.

¿Tiene experiencia a nadie mismo problema en absoluto, o es sólo conmigo? ¿Tiene usted alguna solución para esto?

¿Fue útil?

Solución 2

Parece que no hay incorporado de manera de manejar esto (y no hay respuesta a esta pregunta después de casi 2 semanas). Ya levanté de código personalizado para cuidar de esto. La descripción de la solución es bastante largo, así que he publicado en mi blog. Consulte este post Si está interesado.

Actualización 5/7/2010: que he encontrado una mejor manera de hacer eso, haciendo uso de continuación de tareas. Creo un class ThreadFactory que expone el evento de error que puede ser suscrita por un controlador de nivel superior y proporciona métodos para iniciar una tarea unida con la continuación adecuada.
El código está escrito aquí .

Actualización 4/18/2011:. Código postal de la entrada de blog según el comentario de Nifle

internal class ThreadFactory
{
    public delegate void TaskError(Task task, Exception error);

    public static readonly ThreadFactory Instance = new ThreadFactory();

    private ThreadFactory() {}

    public event TaskError Error;

    public void InvokeError(Task task, Exception error)
    {
        TaskError handler = Error;
        if (handler != null) handler(task, error);
    }

    public void Start(Action action)
    {
        var task = new Task(action);
        Start(task);
    }

    public void Start(Action action, TaskCreationOptions options)
    {
        var task = new Task(action, options);
        Start(task);
    }

    private void Start(Task task)
    {
        task.ContinueWith(t => InvokeError(t, t.Exception.InnerException),
                            TaskContinuationOptions.OnlyOnFaulted |
                            TaskContinuationOptions.ExecuteSynchronously);
        task.Start();
    }
}

Otros consejos

TaskScheduler.UnobservedTaskException Evento es lo que desear:

  

Se produce cuando una excepción no observada en fallo de Tarea está a punto de gatillo   directiva de extensión excepción, que, por defecto, se daría por terminada la   proceso.

Por lo tanto, este evento es similar a DomainUnhandledException que usted ha mencionado en su pregunta, pero se produce sólo para las tareas.

Por cierto nota, que la política no observados excepciones (sí, esto no es una excepción no observadas, MS chicos inventaron nueva palabra ... de nuevo), cambió de .NET 4.0 a .NET 4.5. En .NET 4.0 de excepción cables no observadas hasta la terminación del proceso, pero en .NET 4.5 - no lo hacen. Todo esto es debido a cosas nuevas asíncrono que tendremos en C # 5 y VB 11.

Veo dos opciones que pueden ser utilizados para los fines de la centralización de la gestión de excepciones en TPL:   1. El uso de la tarea de evento no observada excepción del programador de tareas.   2. El uso de las continuaciones de tareas con estado de fallo.

Uso de la tarea de evento no observada excepción del programador de tareas.

El programador de tareas tiene un evento UnobservedTaskException al que puede suscribirse usando el operador + =.

  • Nota 1: En el cuerpo del controlador que necesita para hacer llamadas SetObserved () el argumento UnobservedTaskExceptionEventArgs para notificar a excepción planificador que se manejó
  • .
  • Nota 2:. El gestor se llama cuando las tareas han sido recogidos por el recolector de basura
  • Nota 3:. Si va a esperar en la tarea que todavía se ve obligado a esperar protección contra escritura por bloque try / catch
  • Nota 4:. La política predeterminada para excepciones de tareas no controlada en .Net 4.0 y 4.5 es diferente

Resumen:. Este enfoque es bueno para disparar y olvidar las tareas y para la captura de excepciones escapado de su sistema de tratamiento de excepción centralizada

Uso de las continuaciones de tareas con estado de fallo.

Con TPL puede adjuntar acciones a la tarea a través ContinueWith método (), que tiene opción de acción y la continuación de fijación. Esta acción se denomina después de la terminación de tareas y sólo en los casos especificados por la opción. En particular:

    t.ContinueWith(c => { /* exception handling code */ },
                   TaskContinuationOptions.OnlyOnFaulted);

instala continuidad con el código de control de excepciones a la tarea t. Este código se ejecuta sólo en el caso de tareas cuando t se terminó debido a la excepción no controlada.

  • Nota 1: Obtener valor de la excepción en el código de control de excepciones. Si no, se hace burbujear a cabo.
  • Nota 2:. Código de manejo de excepciones se llamará inmediatamente después de la terminación de tareas
  • Nota 3: Si la excepción se puso en código de control de excepciones no será considerado como controlado, try / catch en espera tarea no será capaz de atraparlo.

creo que va a ser mejor para el manejo de uso de tareas personalizadas heredadas de tareas con gestor de excepciones añadido a través de la continuación excepción centralizada. Y acompañar a este enfoque mediante el uso de la tarea de evento no observada excepción del programador de tareas para los intentos de captura a utilizar tareas no personalizados.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top