none
Bloqueo del UI con el Context Menu RRS feed

  • Pregunta

  • Buenas Compañeros,

    queria comentaros una duda sobre algo que en principio es relativamente sencillo pero me está dando problemas. Tengo un  listbox con elementos de una clase determinada, asociada a cada elemento tengo un context menu con un solo menu-item ("eliminar"). El proceso de eliminar puede ser costoso porque consulto en base de datos y puede tardar unos segundos. Para hacer más agradable la espera al usuario he intentado introducir un progressbar customizado o un textblock avisador "Cargando" pero no me aparecen desde el mismo momento que hago un "tap" sobre el menu-item "eliminar". Para que esté más optimizado he puesto en un hilo secundario (backgroundworker) la consulta a base de datos.

    He probado de varias maneras pero no hay forma que sea instantaneo la respuesta de aparición del progressbar al darle a menu-item del context menu. Debo decir que utilizo progress bar desde otros objectos y me van instantaneamente, por lo que deduzco que se produce un bloqueo de la UI al estar en el context menu. ¿Teneis alguna idea?

     

    saludos


    Cuanto más sabes, más ignorante te crees.
    miércoles, 14 de diciembre de 2011 18:01

Todas las respuestas

  • Hola Pedro,

    lo primero, ¿has comprobado que tu progress bar o textblock se muestran correctamente? (puedes probarlo sin llamar al código del tap del menú item y dejandolos visibles)

    por otro lado, ¿estás seguro de que todo el código que ejecutas en el evento Tap del menu item se ejecuta en el hilo secundario o haces alguna tarea mas?

    Quizá haya alguna otra tarea la que este bloqueando la UI

    Salu2

     

     


    @ayus
    miércoles, 14 de diciembre de 2011 21:00
  • Hola Alberto,

    efectivamente comprobé que se mostraba que no en el momento que clicklaba sino al tiempo, es como que el context menu dejaraba bloqueada la UI porque he tenido que poner un sleep para poder ver mejor lo que pasaba. Nada más abrir el "menuItem_click" activo el progressbar o hago visible el textblock.

    He pensando en algún converter porque realmente no se me ocurre otra cosa. ¿Algo sobre el ModelView?

    saludos


    Cuanto más sabes, más ignorante te crees.
    miércoles, 14 de diciembre de 2011 22:36
  • Hola Pedro,

    y qué código se ejecuta justo después de activar el progressbar en el evento menuItem_click?

    Salu2


    @ayus
    jueves, 15 de diciembre de 2011 8:12
  • Este es el código que ejecuto desde el menuitem_click .

        private void ContextualEliminar_Click(object sender, RoutedEventArgs e)
        {
            barraprogreso.show();
            tipo_carga = 1;
    
            HiloSecundario = new BackgroundWorker();
            HiloSecundario.DoWork += new DoWorkEventHandler(HiloSecundario_DoWork);
            HiloSecundario.RunWorkerCompleted += new RunWorkerCompletedEventHandler(HiloSecundario_RunWorkerCompleted);
            HiloSecundario.RunWorkerAsync();
        }
    


    El "dowork" y "completed" contienen esto :

        void HiloSecundario_DoWork(object sender, DoWorkEventArgs e)
        {
          Dispatcher.BeginInvoke(() =>
          {
             //Hago todo lo que tengo que hacer... (esto se ejecuta perfectamente).
           });
          }
    
        void HiloSecundario_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            BarraProgreso.Hide();
        }
    


    Esto también lo he probado con un Grid - textblock imitando a una barra de progreso pero el resultado es el mismo. Es un problema de bloqueo de UI o de no actualización de la UI. Habia pensado en un converter pero me parece algo complejo en esta situación o  fuera de sitio.

    saludos ;)


    Cuanto más sabes, más ignorante te crees.
    jueves, 15 de diciembre de 2011 8:44
  • Hola de nuevo,

    quizá el problema esté en que lo que haces en el DoWork, lo estás haciendo con el Dispatcher.BeginInvoke, lo que al final se ejcutará en el thread de UI.

    Prueba a ejecutar el código que tarda mucho, fuera del Dispatcher.BeginInvoke para que se ejcute realmente en el hilo del backgroundworker. Solamente llama al dispatcher cuando tengas que actualizar algo en los controles del la UI, por ejemplo el valor del progressbar.

    Algo así

    void HiloSecundario_DoWork(object sender, DoWorkEventArgs e)
        {

    //Hago todo lo que tengo que hacer... (esto se ejecuta perfectamente).

          Dispatcher.BeginInvoke(() =>
          {

    // Llamadas a actualizaciones de la UI, por ejemplo cambiar el progressbar.

                    });
          }

    No sé si puedes probar esto y ver si funciona.

    Salu2


    @ayus
    jueves, 15 de diciembre de 2011 10:09
  • Gracias Alberto pero hace lo mismo. Buscaré otra solución.

     

    un Abrazo


    Cuanto más sabes, más ignorante te crees.
    • Editado Pedro Net lunes, 26 de diciembre de 2011 15:46
    lunes, 26 de diciembre de 2011 15:45