Как мне "DoEvents" в WPF?

Я читал, что версия C# выглядит следующим образом:

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

однако я не могу понять, как поместить пустой делегат в VB.NET, as VB.NET не поддерживает анонимные методы. Идеи?

Edit: возможно, это?

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

             End Sub))

5 ответов


VB.NET поддерживает анонимные делегаты, но только как функции с одним оператором. (Multi-заявление анонимные функции и анонимные Subs были добавлены в VB10 в .NET 4)

чтобы обеспечить контекст, DoEvents был разработан, чтобы позволить однопоточной среде обновлять пользовательский интерфейс и обрабатывать другие сообщения Windows во время работы. Не должно быть никакой пользы в вызове DoEvents (или, как вы делаете здесь, делая это косвенно, выполняя функцию "null" на dispatcher) из другого потока, так как поток пользовательского интерфейса должен обновляться сам по себе.

в интересах отвечая на ваш вопрос, хотя, самый простой вариант будет что-то вроде этого:

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

но, опять же, я не вижу, что это реально выполнить.

если то, что вы ищете, просто как выполнить код в потоке пользовательского интерфейса (например,Control.Invoke из Windows forms), затем Dispatcher.Invoke (что вы используете) правильно, вам просто нужно переведите встроенные анонимные методы в незаметные функции и передайте их как делегаты. Там могут быть некоторые, которые вы можете уйти, оставив как анонимные. Например, если все, что вы делаете, это обновление индикатора выполнения, вы можете сделать:

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

это работает, потому что все назначения возвращают значение, которое было сохранено в левой части назначения. Однако вы не можете просто вызвать sub (следующее не будет компилироваться, если SomeFunctionName возвращает a значение):

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

иными словами, любые анонимные делегаты в C# код, который:

  • являются более чем одним утверждением
  • не возвращайте значение (это означает, что это всего лишь один вызов метода, а не функции)

тогда вам придется создавать функции для них и передавать делегаты этим функциям, а не вставлять код, как в C#.


вы можете просто вызвать этот метод, если хотите, чтобы что-то было обновлено в пользовательском интерфейсе:

System.Windows.Forms.Application.DoEvents

мы используем его в наших приложениях WPF Window и XBAP.


у вас есть два вопроса здесь, поэтому я собираюсь добавить два ответа. Здесь я отвечаю "Как делать DoEvents в WPF". Bea Stollnitz покрывает это на ее блог, и вот код в 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

используйте ключевое слово Function:

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

или просто используйте диспетчер, чтобы сделать себе Doevents () для WPF:

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