Update UI from background Thread

隐身守侯 提交于 2019-12-29 08:23:10

问题


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!


回答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);



回答2:


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.




回答3:


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




回答4:


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.




回答5:


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!");
}



回答6:


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



来源:https://stackoverflow.com/questions/7959005/update-ui-from-background-thread

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!