Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I "DoEvents" in WPF?

Tags:

vb.net

wpf

I've read that the C# version is as follows:

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

However I cannot figure out how to put the empty delegate into VB.NET, as VB.NET does not appear to support anonymous methods. Ideas?

Edit: Possibly this?

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

             End Sub))
like image 580
NibblyPig Avatar asked Apr 19 '10 12:04

NibblyPig


People also ask

How do I use DoEvents in C#?

DoEvents() can be used to process the messages waiting in the queue on the UI thread when performing a long-running task in the UI thread. This has the benefit of making the UI seem more responsive and not "locked up" while a long task is running.

Do events in VB net?

DoEvents method has the same behavior as the DoEvents method. When you run a Windows Forms application, it creates a new form, which then waits for events to be handled. Each time the form handles an event, such as a button click, it processes all the code associated with that event. All other events wait in the queue.


3 Answers

VB.NET does support anonymous delegates, but only as single-statement functions. (Multi-statement anonymous functions and anonymous Subs have been added to VB10 in .NET 4)

To provide context, DoEvents was designed to allow a single-threaded environment to update the UI and process other Windows messages while work was being done. There should be no benefit to calling DoEvents (or, as you're doing here, doing so indirectly by executing a "null" function on the dispatcher) from another thread, as the UI thread should be updating by itself.

In the interest of answering your question, though, the easiest option would be something like this:

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

But, again, I can't see what this would actually accomplish.

If what you're looking for is simply how to execute code on the UI thread (like the Control.Invoke from Windows forms), then Dispatcher.Invoke (which is what you're using) is correct, you'll just have to translate your inline anonymous methods into discreet functions and pass those as delegates. There may be some that you can get away with leaving as anonymous. For example, if all you're doing is updating a progress bar, you could do:

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

This works because all assignments return the value that was stored in the left side of the assignment. You could not, however, just call a sub like this (the following won't compile unless SomeFunctionName returns a value):

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

In other words, any of the anonymous delegates that are in the C# code that either:

  • Are more than one statement
  • Do not return a value (meaning it's just a single call to a method, not a function)

Then you'll have to create functions for those and pass delegates to those functions rather than inlining the code as you have in C#.

like image 175
Adam Robinson Avatar answered Sep 17 '22 22:09

Adam Robinson


You could simply call this method if you want something to be refreshed on the UI:

System.Windows.Forms.Application.DoEvents

We are using it on our WPF Window and XBAP applications.

like image 33
Jojo Sardez Avatar answered Sep 21 '22 22:09

Jojo Sardez


You've got two questions here, so i'm going to add two answers. Here, i'm answering "how to do DoEvents in WPF". Bea Stollnitz covers this on her blog, and here's the code in 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
like image 34
Rob Fonseca-Ensor Avatar answered Sep 21 '22 22:09

Rob Fonseca-Ensor