none
Problemas con OpenFileDialog en aplicaciones multithread

    Pregunta

  • Hola!

    Estoy implementando una aplicación multihilo que necesita escuchar un puerto y desencadenar una serie de acciones, a la vez que en otro hilo, ejecuta otra serie de tareas. El problema es que OpenFileDialog.ShowDialog() no se ejecuta correctamente en ninguno de los hilos. Según creo, puede deberse a dos cosas:

    1- OpenFileDialog no identifica a la ventana de nivel superior propietaria del mismo    

    2- Existe un problema de seguridad en el acceso a los archivos desde hilos diferentes

    La primera de las opciones la he intentado solventar indicándole el propietario (mi_OpenFileDialog.ShowDialog(Me), por ejemplo), pero no he podido lograr resultados. 

    Simplemente, la ejecución del programa se detiene sin más. No da excepción de ningún tipo y los bloques Try-Catch, es como si no existiesen.

    La segunda opción la he estado estudiando, pero los permisos de acceso se cambian sobre los archivos en concreto, y no actúan sobre el control (OpenFileDialog), que en ningún caso llega siquiera a desplegarse.

    Les agradezco cualquier aporte que me pueda orientar para poder salir del paso.

    Saludos!

    sábado, 29 de abril de 2017 13:30

Respuestas

  • El problema es que el OpenFileDialog, al igual que todos los demás controles de WinForms, solo es lícito usarlo desde el hilo que creó la pantalla. Da igual la ventana que sea propietaria, puesto que todas ellas se ejecutan en el hilo de la interfaz de usuario. También dan igual los permisos de seguridad de los archivos, todos los hilos usan los mismos permisos.

    Así que, para mostrar el OpenFileDialog, primero tienes que transferir la ejecución al hilo de la interfaz. Esto se puede conseguir llamando al método Invoke de cualquiera de los controles, incluyendo el propio formulario. Si el código lo tienes escrito dentro de la clase del Form (aunque se ejecute en otro hilo), puedes hacerlo así:

    Me.Invoke(AddressOf MostrarDialogo)

    Siendo MostrarDialogo una Sub que añadirás al programa y que sirva para mostrar el OpenFileDialog. Nótese que esta Sub se ejecutará en el hilo principal, por lo que se quedará "parado" en el Invoke si el hilo principal está ocupado en ese momento haciendo alguna otra cosa.

    sábado, 29 de abril de 2017 14:02
  • Si al diálogo lo invocas desde "otro" thread , deberías hacerlo usando el Invoke del control y por medio de un delegado. Cuando usas este método, win forms espera a que te encuentres en el thread de la gui para hacer el llamado a showdialog.

    No es un problema de seguridad. Simplemente estos controles están diseñados para intercambiar window messages (enviar y recibir) con ventanas que están en el mismo thread.

    ---

    Ok, lo que ya te dijo Alberto.

    sábado, 29 de abril de 2017 14:04

Todas las respuestas

  • El problema es que el OpenFileDialog, al igual que todos los demás controles de WinForms, solo es lícito usarlo desde el hilo que creó la pantalla. Da igual la ventana que sea propietaria, puesto que todas ellas se ejecutan en el hilo de la interfaz de usuario. También dan igual los permisos de seguridad de los archivos, todos los hilos usan los mismos permisos.

    Así que, para mostrar el OpenFileDialog, primero tienes que transferir la ejecución al hilo de la interfaz. Esto se puede conseguir llamando al método Invoke de cualquiera de los controles, incluyendo el propio formulario. Si el código lo tienes escrito dentro de la clase del Form (aunque se ejecute en otro hilo), puedes hacerlo así:

    Me.Invoke(AddressOf MostrarDialogo)

    Siendo MostrarDialogo una Sub que añadirás al programa y que sirva para mostrar el OpenFileDialog. Nótese que esta Sub se ejecutará en el hilo principal, por lo que se quedará "parado" en el Invoke si el hilo principal está ocupado en ese momento haciendo alguna otra cosa.

    sábado, 29 de abril de 2017 14:02
  • Si al diálogo lo invocas desde "otro" thread , deberías hacerlo usando el Invoke del control y por medio de un delegado. Cuando usas este método, win forms espera a que te encuentres en el thread de la gui para hacer el llamado a showdialog.

    No es un problema de seguridad. Simplemente estos controles están diseñados para intercambiar window messages (enviar y recibir) con ventanas que están en el mismo thread.

    ---

    Ok, lo que ya te dijo Alberto.

    sábado, 29 de abril de 2017 14:04