sirve que progressbar para ejemplo java swing swingworker

java - que - ¿Cómo debo manejar excepciones cuando uso SwingWorker?



swingworker java ejemplo (7)

Debería haber aclarado mi publicación original. No capture simplemente ciertos tipos de excepciones en el método done (). Cualquier código que se ejecute en doInBackground () podría arrojar cualquier tipo de Excepción y solo atrapar las Excepciones en su pregunta puede llevar a que se generen Excepciones en el EDT (Subproceso de envío de evento o subproceso principal de la GUI). La captura de todos los tipos de Excepciones en el método done () es solo una buena costumbre al usar SwingWorkers.

@Override protected void done() { try { if(!super.isCancelled()) { super.get(); } } catch(Exception ex) { ex.printStackTrace(); } }

Utilizo SwingWorker en Java 6 para evitar ejecutar código de larga ejecución en el hilo de envío del evento.

Si la llamada a get () en mi método done () devuelve una excepción, ¿cuál es una forma apropiada de manejar la excepción?

Estoy particularmente preocupado por posibles interruptedExceptions. El ejemplo de JavaDoc simplemente ignora la excepción, pero he aprendido a través de los años que tragar excepciones lleva a código difícil de depurar.

Un uso de muestra es el siguiente:

new SwingWorker<String, Void>() { @Override protected String doInBackground() throws Exception { // do long-running calculation return result; } @Override protected void done() { try { setTextField(get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } }.execute();


Depende mucho del tipo de errores que puedan surgir del trabajo en segundo plano. Si el trabajo en doInBackground arroja una excepción, se propagará al método hecho como ExecutionException anidada. La mejor práctica en este caso sería manejar la excepción anidada, en lugar de la ExecutionException.

Por ejemplo: si el hilo del trabajador arroja una excepción que indica que se ha perdido la conexión de la base de datos, probablemente desee volver a conectar y reiniciar el trabajo. Si el trabajo a realizar depende de algún tipo de recurso que ya esté en uso, sería una buena idea ofrecer el uso de una opción de reintento o cancelación. Si la excepción lanzada no tiene ninguna implicación para el usuario, solo registre el error y continúe.

Por lo que recuerdo, creo que la InterruptedException no será un problema aquí ya que realiza la llamada al método get en el método done, ya que la InterruptedException solo se lanzará si la llamada get se interrumpe mientras se espera que el trabajo en segundo plano terminar. Si ocurriera un evento inesperado como ese, probablemente desee mostrar un mensaje de error y salir de la aplicación.


Es una publicación anterior, pero quiero hacer algunas aclaraciones:

SwingWorker.get arroja InterruptedException, ExecutionException como excepciones marcadas.

Además arroja una excepción no controlada muy específica que es CancellationException. Por supuesto, podría arrojar cualquier excepción no verificada, pero CancellationException no es "excepcional" e inesperada. Se lanza cuando intentas llamar al método get después de que se haya llamado cancelar.

ExecutedException se lanza cuando se lanza una excepción dentro de DoInBackground. La excepción original se envuelve dentro de ExecutionException. Cuando se llame al método get (), se lanzará ExecutionException. La idea de sacar la excepción original y gestionar eso es buena. (Como señaló Emil H).

CancellationException está desmarcada y en mi opinión debe ser revisada. La única excusa para que la implementación de la API no la tenga marcada es que tiene un método de estado isCancelled ().
Tu también puedes:
- test isCancelled () y si es verdadero NO llame a get () ya que lanzará CancellationException
- rodee get () con try-catch y agregue la CancellationException, que como no seleccionada no será solicitada por el compilador
- El hecho de que CancellationException no esté marcado le permite olvidarse de todas esas cosas y obtener una agradable sorpresa.
- Haz cualquier cosa porque no cancelarás al trabajador

InterruptedException. Si cancela un SwingThread con cancelar (verdadero), la primera llamada al método interrumpible (con seguridad Thread.sleep, this.wait, quizás algunos métodos IO) en doInBackground arrojará InterruptException. Pero esta excepción no está incluida en ExecuteException. DoInBackground se deja terminar con una excepción interrumpida. Si se atrapa y se convierte en alguna otra excepción, se ignorarán porque, en este momento, cancelar ya ha invocado a SwingThread.done en el EDT, y si lo ha hecho ha llamado a get, ha obtenido solo la CancelaciónExcepción estándar. ¡No es una excepción interrumpida!

Si cancela con cancel (false), no se genera InterruptException dentro de doInBackground. Lo mismo si cancela con cancelar (verdadero) pero no hay llamadas de método interrumpibles dentro de DoInBackground. En estos casos, doInBackground seguirá su ciclo natural. Este ciclo debería probar el método isCancelled y salir con gracia. Si doInBackground no lo hace, se ejecutará para siempre. No he probado la presencia de tiempos de espera, pero no lo creo.

Para mí, sigue siendo solo un área gris . ¿En qué casos se lanza InterruptedException by get? Me gustaría ver un código corto, ya que no podría producir una excepción similar. :-)

PD. He documentado en otra pregunta y respuesta que se llama al oyente de cambio de estado y hecho en caso de cancelación antes de que se cierre doInBackground. Como esto es cierto, esto -que no es un error- requiere una atención especial cuando se diseña el método doInBackground. Si está interesado en esto, vea SwingWorker: ¿cuándo exactamente se llama método hecho?


Esta es una cuestión tanto de interfaz como de manejo de errores. Muchas aplicaciones agregan una pequeña tabla que enumera los trabajos en segundo plano en ejecución. Una excepción en uno de ellos puede mostrar la fila de la tabla que produjo un error, o hacer algo tan perturbador como presentar una alerta. Depende de la gravedad de la excepción. Creo que la pregunta más difícil que probablemente tendrá que responder es de cuántos tipos de excepciones potencialmente diferentes estamos hablando, y cuál es su gravedad relativa.

Creo que un compromiso simple podría ser presentar una alerta modal para sus errores más graves, y cualquier otra cosa, simplemente registre la ocurrencia hasta que a) impida al usuario seguir adelante o b) el usuario cierre el documento / ventana, momento en el cual puede mostrar una lista de las excepciones que ocurrieron durante las tareas de procesamiento en segundo plano al mismo tiempo que pregunta si desea guardar los almacenamientos intermedios no guardados, por ejemplo.


Lo que recomendaría es permitir que el error se propague todo el camino hasta donde se inició la acción.

Por ejemplo, si un usuario hace clic en un botón para obtener datos de una fuente de datos. Si se produce un problema, ya sea un error de credencial, un error de red, un error de base de datos o cualquier otra cosa, no sería apropiado que tuviera lógica dentro de ese hilo de trabajo para intentar resolverlo allí mismo.

Pero si permite que se propague al lugar donde comenzó la tarea, desde allí puede tomar las correcciones de error adecuadas, como abrir el cuadro de diálogo de credenciales una vez más, mostrar un cuadro de diálogo "intentar de nuevo" o incluso mostrar un mensaje de error.


Supongamos que se trata de una aplicación GUI, es posible que desee proporcionar una retroalimentación visual sobre la operación fallida en la excepción.


Supongo que no obtendrás muchas de estas preguntas con C #. Debes entender cuál es la excepción y lidiar con ella de manera apropiada (que generalmente es para dejarla ir más arriba en la pila).

InterruptedException - Lanzada cuando se interrumpe un hilo (por Thread.interrupt ) cuando se espera (aproximadamente). ¿Por qué querrías que un hilo sea interrumpido? Por lo general, desea que el hilo detenga lo que está haciendo: reinicie el estado de interrupción y salga. Por ejemplo, el PlugIn interrumpirá los subprocesos del applet si continúan por mucho más tiempo después de que un applet haya desaparecido. Sin embargo, en este caso, siempre que se done correctamente, no debe esperar. Por lo tanto, sería apropiado ajustar la excepción en una IllegalStateException (y los documentos de la API probablemente deberían indicar eso). Es una API realmente mala. El modo publish / process probablemente tenga más sentido.

ExecutionException : debe tratar la excepción envuelta. Si no espera un tipo particular de excepción, envuélvalo en una excepción sin marcar.

En general, sugeriría una clara separación entre lo que sucede en el EDT y lo que sucede con el EDT. Por lo tanto, evite SwingWorker en el código de producción.