2010-04-19 15 views
6

He leído que la versión C# es la siguiente:¿Cómo hago "DoEvents" en WPF?

Application.Current.Dispatcher.Invoke(
      DispatcherPriority.Background, 
      new Action(delegate { })); 

sin embargo no puedo encontrar la manera de poner el delegado desembocan en VB.NET, como VB.NET no parece apoyar los métodos anónimos. Ideas?

Editar: Posiblemente esto?

Application.Current.Dispatcher.Invoke(
    DispatcherPriority.Background, 
    New Action(Sub() 

      End Sub)) 
+0

DoEvents? Creo que solían utilizar DoEvents en VB6, antes de que las personas se dieran cuenta de que una aplicación podría tener algo más que el hilo de UI. – Will

+0

Bueno, la convención moderna es usar Thread.Sleep (1) o similar, pero esto no funciona cuando necesita saltar de un hilo temporalmente para permitir que la interfaz de usuario se actualice y permanezca en el medio de un ciclo de procesamiento en WPF. – NibblyPig

+1

@SLC: si está procesando en otro hilo, entonces no debería necesitar decirle a la interfaz de usuario que se actualice solo (en una especie de actualización general). –

Respuesta

6

VB.NET es compatible con los delegados anónimos, pero sólo como funciones de un único estado. (instrucción múltiple funciones anónimas y anónimos Sub s se han añadido a VB10 en .NET 4)

para proporcionar el contexto, DoEvents fue diseñado para permitir un entorno de un solo subproceso para actualizar los otros mensajes de Windows de interfaz de usuario y de proceso mientras que el trabajo era Siendo hecho. No debería haber ningún beneficio al llamar al DoEvents (o, como lo está haciendo aquí, hacerlo indirectamente al ejecutar una función "nula" en el despachador) desde otro subproceso, ya que el subproceso de interfaz de usuario debería actualizarse por sí mismo.

Con el fin de responder a su pregunta, sin embargo, la opción más fácil sería algo como esto:

Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, _ 
    New Action(Function() 7)) 

Pero, de nuevo, no puedo ver lo que esto realmente lograr.

Si lo que está buscando es simplemente cómo ejecutar código en el hilo de la interfaz de usuario (como el Control.Invoke de formularios de Windows), entonces Dispatcher.Invoke (que es lo que está usando) es correcto, solo tendrá que traduzca sus métodos anónimos en línea en funciones discretas y páselos como delegados. Puede haber algunos con los que puede salirse con el anonimato. Por ejemplo, si todo lo que está haciendo es la actualización de una barra de progreso, que podría hacer:

Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, _ 
    New Action(Function() progressBar.Value = 100)) 

Esto funciona porque todas las asignaciones devuelven el valor que se almacena en el lado izquierdo de la asignación. Se podría, sin embargo, acaba de llamar a un sub como esto (la siguiente no se compilará a menos SomeFunctionName devuelve un valor):

Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, _ 
    New Action(Function() SomeFunctionName(params))) 

En otras palabras, cualquiera de los delegados anónimos que se encuentran en el código C# que sea :

  • son más de una sentencia
  • no devuelven un valor (lo que significa que sólo una sola llamada a un método, no una función)

entonces te h para crear funciones para aquellos y pasar delegados a esas funciones en lugar de escribir el código como lo hace en C#.

+0

La interfaz de usuario solo se puede actualizar si es posible, que se encuentra al final de una función. Esta es la razón por la que su aplicación no responde si coloca un bucle en ella, e incluso con un hilo de suspensión no actualizará los componentes de la UI en un bucle sin hacer una Invocación en formularios de Windows para forzar un cambio al otro hilo. Yo especulo que esto es lo mismo. – NibblyPig

+0

Puede cambiar la función() a Sub() y solo tiene un Sub() vacío como he especulado en mi edición, porque acabo de confirmarlo en el código y parece funcionar. – NibblyPig

+3

@SLC: esto solo es cierto si lo que estás haciendo * tiene lugar en el hilo de la interfaz de usuario *. Si el código se está ejecutando en otro hilo, entonces esto no es necesario. ** Si lo que estás haciendo * está * ejecutándose en el hilo de la interfaz de usuario y tarda lo suficiente como para requerir una actualización de UI explícita, entonces debería moverse a otro hilo. ** –

0

utilizar la palabra clave Función:

Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, New Action(Function() Do ... End Function)) 
+0

El problema es que la acción no hace nada, así que ¿qué puedo poner allí que es "nada" "¿?" También una función devuelve una variable. – NibblyPig

+0

¿Se compila si solo eliminas los puntos? ¿De qué versión de VB/.NET estamos hablando aquí? –

1

Aquí tienes dos preguntas, así que voy a agregar dos respuestas. Aquí, estoy respondiendo "cómo hacer DoEvents en WPF".Bea Stollnitz cubre esto en her blog, y aquí está el código en VB:

publicShared Sub WaitForPriority(priority As DispatcherPriority) 
    Dim frame As New DispatcherFrame() 
    Dim dispatcherOperation As DispatcherOperation = Dispatcher.CurrentDispatcher.BeginInvoke(priority, New DispatcherOperationCallback(ExitFrameOperation), frame) 
    Dispatcher.PushFrame(frame) 
    If dispatcherOperation.Status <> DispatcherOperationStatus.Completed Then 
     dispatcherOperation.Abort() 
    End If 
End Sub 

Private Shared Function ExitFrameOperation(obj As Object) As Object 
    (DirectCast(obj, DispatcherFrame)).[Continue] = False 
    Return Nothing 
End Function 
3

Usted simplemente puede llamar a este método si desea algo que se actualizará en la interfaz de usuario:

System.Windows.Forms.Application.DoEvents 

Nos aplicamos en una nuestras aplicaciones WPF Window y XBAP.

0

o simplemente utilizar despachador para hacerse un DoEvents() para WPF:

'The WPF equivalent of DoEvents!! 
Public Sub DoEvents() 
    Dispatcher.Invoke(New Action(Function() 
            Return Nothing 
           End Function), DispatcherPriority.ContextIdle, Nothing) 
End Sub 
Cuestiones relacionadas