Как делают меня “DoEvents” в WPF?

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

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

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

Править: Возможно это?

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

             End Sub))
6
задан NibblyPig 19 April 2010 в 12:41
поделиться

4 ответа

VB.NET поддерживает анонимные делегаты, но только как функции с одним оператором. (Анонимные функции с несколькими операторами и анонимные Sub s были добавлены в VB10 в .NET 4)

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

Однако, чтобы ответить на ваш вопрос, проще всего было бы что-то вроде этого:

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

Но, опять же, я не вижу, что это на самом деле даст.

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

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

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

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

Другими словами, любой из анонимных делегатов, содержащихся в коде C # что либо:

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

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

6
ответ дан 9 December 2019 в 22:31
поделиться

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

System.Windows.Forms.Application.DoEvents

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

4
ответ дан 9 December 2019 в 22:31
поделиться

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

Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, New Action(Function() Do ... End Function))
0
ответ дан 9 December 2019 в 22:31
поделиться

У вас есть два вопроса, поэтому я собираюсь добавить два ответа. Здесь я отвечаю «как делать DoEvents в WPF». Беа Штольниц рассказывает об этом в своем блоге , а вот код в 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
1
ответ дан 9 December 2019 в 22:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: