0

This is just a curious question. Which one is the best way to update UI from another thread. First, this one:

private delegate void MyDelegateMethod();
void MyMethod()
{
    if (unknowncontrol.InvokeRequired)
    {
        this.BeginInvoke(new MyDelegateMethod(MyMethod));
        return;
    }
    unknowncontrol.property = "updating!";
}

On the other hand:

Invoke((System.Threading.ThreadStart)delegate()
{
    unknowncontrol.property = "updating!";
});

Or, is there a better way to do this?

Of course this is for WinForms, for WPF there's the dispatcher. How is the code for WPF?

I'm asking, 'cause, in the past I experienced errors when updating UI from a raised event using both of the options above. The kind of error like: "there is no source code available". I assume all of us have seen them :D.

Thanks, and have a nice day!

BlackCath
  • 816
  • 13
  • 23
  • Your doing it exactly how you should. In the future post actual code if you want feedback. – Security Hound Oct 31 '11 at 20:01
  • 1
    If you have problem with some of your code, post that. I have never seen an "there is no source code available" error. If you mean the message VS gives when you try to look at code of some framework method, that's not an error. The actual message of the thrown exception is the important bit. – svick Oct 31 '11 at 20:05
  • Is there any performance penalty for calling `Control.Invoke()` or `Control.BeginInvoke()` from the UI thread? I use the first pattern because it doesn't bother with the Invoke call if it's not necessary. – harlam357 Oct 31 '11 at 20:14

6 Answers6

1

Check out Roy Osherove's blog post on this: http://osherove.com/blog/2006/3/1/the-3-ways-to-create-a-thread-safe-gui-with-net-20-with-one.html

delegate void Func<T>(T t);
Func del = delegate
{

  // UI Code goes here
};
Invoke(del);
Chris Andrews
  • 1,881
  • 3
  • 21
  • 31
0

The default Action delegate worked 90% of the time:

private void Log(String value)
{
    // Verify that we're on the same thread
    if (textBox1.InvokeRequired)
    {
        // We're not on the same thread - Invoke the UI thread
        textBox1.Invoke(new Action<string>(Log), value);
        return;
    }

    // We're on the same thread - Update UI
    textBox1.Text += value + "\r\n";
}

private void OnSomethingHappened()
{
    Log("Something happened!");
}
Nitay
  • 4,193
  • 6
  • 33
  • 42
0

Use [Dispatcher.Invoke(DispatcherPriority, Delegate)] to change the UI from another thread or from background.

Step 1. Use the following namespaces

using System.Windows;
using System.Threading;
using System.Windows.Threading;

Step 2. Put the following line where you need to update UI

Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate
{
    //Update UI here
}));

Syntax

[BrowsableAttribute(false)]
public object Invoke(
  DispatcherPriority priority,
  Delegate method
)

Parameters

priority

Type: System.Windows.Threading.DispatcherPriority

The priority, relative to the other pending operations in the Dispatcher event queue, the specified method is invoked.

method

Type: System.Delegate

A delegate to a method that takes no arguments, which is pushed onto the Dispatcher event queue.

Return Value

Type: System.Object

The return value from the delegate being invoked or null if the delegate has no return value.

Version Information

Available since .NET Framework 3.0

Vineet Choudhary
  • 7,433
  • 4
  • 45
  • 72
0

I typically used the first model, but that's only because I found it clearer. There isn't really going to be an effective difference between the two.

Dave C
  • 429
  • 3
  • 9
0

As i see it the best way is to set a CLR-property to which the ui-element's property is bound to.

H.B.
  • 166,899
  • 29
  • 327
  • 400
0

The first method (BeginInvoke) ensures that the UI update code executes on the same thread that created the control. The 2nd method does not. Having all UI updating code execute on the same thread avoids alot of threading issues and allows you to use controls that are not necessarily thread-safe.

Dylan Smith
  • 22,069
  • 2
  • 47
  • 62