2010-07-14 15 views
18

Probablemente una pregunta estúpida ... pero aquí va de todos modos ...manija en Quartz.net

que han establecido cuarzo, y pueden programar trabajos, y puedo confirmar que los trabajos (que implementa la interfaz IJob) estan trabajando.

En cuanto a la documentación en el sitio, (lección 3 del tutorial):

El único tipo de excepción que se le permite a pasos de La método de ejecución es JobExecutionException.

Me gustaría que cuando se produce una excepción que no he manejado explícitamente, se debe lanzar una JobExecutionException, para que pueda iniciar sesión en la aplicación 'principal'. He envuelto mi código en una captura de prueba, y he lanzado JobExecutionException, pero ¿ahora dónde manejarlo?

No llamo al método de ejecución en ningún lado, que es manejado por Quartz (en un hilo separado). Entonces, ¿cómo manejo ese error cuando ocurre? Realmente no quiero tragar el error en el Trabajo

+1

OK, investigué un poco más, y parece que JobListener es lo que estoy buscando. Ahora para descubrir cómo manejaría la excepción. – tardomatic

+0

annnnnd .... sin suerte.incluso con un oyente, la aplicación se bloquea al lanzar una excepción. ¡AYUDA! – tardomatic

+0

@ tardomatic: si tiene un escucha de trabajo conectado a un nombre de trabajo/grupo, se llamará al oyente independientemente de si el trabajo tiene éxito o falla. Después de arrojar una JobExecutionException (en función de que detecte un error), Quartz considerará que el trabajo no está completo (por definición, Quartz considera que un trabajo está completo * a menos que * dispare una JobExecutionException). Ahora, cuando está en el método JobWasExecuted() del oyente, puede verificar el parámetro JobExecutionException para ver si está configurado. Ahora sabe si el trabajo falló y, opcionalmente, puede realizar tareas de limpieza, etc. antes de volver a ejecutar el trabajo en el futuro. – Matt

Respuesta

10

Normalmente, usted podría configurar el método de ejecución de su trabajo de la siguiente manera:

try 
{ 
    // the work you want to do goes here 
} 
catch (ExceptionTypeYouWantToHandle1 ex1) 
{ 
    // handle exception 
} 
catch (ExceptionTypeYouWantToHandle2 ex2) 
{ 
    // handle exception 
} 
// and so on 
catch (Exception ex) 
{ 
    // something really unexpected happened, so give up 
    throw new JobExecutionException("Something awful happened", ex, false); // or set to true if you want to refire 
} 

En este punto, el programador sí registrará la excepción a donde quiera está registrando (basado en la configuración).

+1

Ha pasado tanto tiempo desde que trabajé en esto, ya no tengo el código disponible para probar si esto funciona. Sin embargo, es dudoso, ya que lanzar el JobExecutionException es el problema. Lanzo eso, pero Quartz no lo maneja y lo registra como lo mencionas, simplemente burbujeaba hasta el final como una excepción no controlada. – tardomatic

+0

... no se lo puede decir en serio ... * los atrapará a todos * no se supone que sean las mejores prácticas ... sería mucho mejor agregar un oyente y reaccionar a las terminaciones de trabajo con una excepción ... –

+0

La mejor práctica es hacer que su trabajo maneje sus propias excepciones. ¿Está recomendando crear un oyente por separado para cada tipo de trabajo solo para manejar excepciones? – jvilalta

13

He resuelto este problema mediante el uso de una clase base para capturar todas las excepciones:

public abstract class JobBase : IJob 
{ 
    protected JobBase() 
    { 
    } 

    public abstract void ExecuteJob(JobExecutionContext context); 

    public void Execute(JobExecutionContext context) 
    { 
     string logSource = context.JobDetail.FullName; 

     try 
     { 
      ExecuteJob(context); 
     } 
     catch (Exception e) 
     { 
      // Log exception 
     } 
    } 
} 

Su clase de trabajo debe desea:

public class SomeJob : JobBase 
{ 
    public SomeJob() 
    { 
    } 

    public override void ExecuteJob(JobExecutionContext context) 
    { 
     // Do the actual job here 
    } 
} 
+1

Buena solución para habilitar el registro común entre trabajos de cuarzo diferentes. ¡Gracias! – nocarrier

+0

... no se puede hablar en serio ... * los atrapará a todos * no se supone que sean las mejores prácticas ... sería mucho mejor agregar un oyente y reaccionar a las terminaciones de trabajo con una excepción ... –

+0

No estoy seguro de seguir tu línea de pensamiento, ¿me importa mostrar un ejemplo? (Un enlace al código de pastebin sería perfecto) –

5

Como ya se ha mencionado, la forma correcta de "detectar "JobExecutionException a nivel global es implementar y registrar un IJobListener y verificar si el parámetro JobExecutionException en el método JobWasExecuted() es! = Null.

Sin embargo, el problema que tuve (y a juzgar por el comentario adicional del OP, se enfrentó a esto también) fue que Quartz no manejó la JobExecutionException (como debería) que resultó en una excepción no controlada matando la aplicación.

Hasta ahora, estaba usando la DLL precompilada del paquete de lanzamiento Quartz.NET 2.0.1 (.NET3.5). Para llegar al fondo del problema, hice referencia al proyecto/código fuente de Quartz y para mi asombro, ¡de repente estaba funcionando!

Como punto de interés, este es el cuarzo código de la biblioteca que ejecuta el IJob y se ocupa de la JobExecutionException:

try { 
    if (log.IsDebugEnabled) { 
     log.Debug("Calling Execute on job " + jobDetail.Key); 
    } 
    job.Execute(jec); 
    endTime = SystemTime.UtcNow(); 
} catch (JobExecutionException jee) { 
    endTime = SystemTime.UtcNow(); 
    jobExEx = jee; 
    log.Info(string.Format(CultureInfo.InvariantCulture, "Job {0} threw a JobExecutionException: ", jobDetail.Key), jobExEx); 
} catch (Exception e) { 
    // other stuff here... 
} 

Lo siguiente fue hacer referencia a mi DLL recién compilado direcly y esto estaba trabajando como bien. Lamentablemente, no puedo decirte por qué funciona esto y actualmente no tengo tiempo para profundizar más, pero quizás esto ayude a alguien. Tal vez algún otro pueda confirmar esto e incluso contribuir con una explicación. Puede tener algo que ver con diferentes plataformas de destino (x86/64bit)?

+1

+, ¡eres el único que lo hizo bien! ... ¡Felicitaciones! –

+0

Esto es incorrecto. catch (JobExecutionException jee) { endTime = SystemTime.UtcNow(); jobExEx = jee; Captura y maneja la excepción JobExcecutionException .. No veo un lanzamiento, por lo tanto, se maneja en este momento y no se lanzará, causando una excepción no controlada. La excepción se asigna a jobExEx y TAMBIÉN se envía al oyente. Cuestiono la cordura de tener un solo oyente manejando las excepciones para todos los trabajos o incluso tener un oyente por trabajo solo para manejar las excepciones. Todos los trabajos deben saber cómo manejar sus propias excepciones. – jvilalta

+3

@jvilalta: Puede haber un malentendido. El código entre comillas es el código real de la biblioteca Quartz.NET. NO el código de la aplicación. Solo quería señalar cómo Quartz maneja la JobExecutionException internamente. –