Как мне сделать DoEvents в WPF? - PullRequest
6 голосов
/ 19 апреля 2010

Я читал, что версия 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))

Ответы [ 5 ]

6 голосов
/ 19 апреля 2010

VB.NET поддерживает анонимных делегатов, но только как функции с одним оператором. (Анонимные функции с несколькими утверждениями и анонимные Sub были добавлены в 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))

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

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

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

  • Более одного утверждения
  • Не возвращать значение (т. Е. Это всего лишь один вызов метода, а не функции)

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

4 голосов
/ 20 апреля 2010

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

System.Windows.Forms.Application.DoEvents

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

1 голос
/ 20 апреля 2010

У вас есть два вопроса здесь, поэтому я собираюсь добавить два ответа. Здесь я отвечаю "как сделать 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
0 голосов
/ 01 августа 2015

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

    'The WPF equivalent of DoEvents!!
Public Sub DoEvents()
    Dispatcher.Invoke(New Action(Function()
                                     Return Nothing
                                 End Function), DispatcherPriority.ContextIdle, Nothing)
End Sub
0 голосов
/ 19 апреля 2010

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

Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, New Action(Function() Do ... End Function))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...