简体   繁体   English

从后台线程更新UI

[英]Update UI from background Thread

This is just a curious question. 这只是一个奇怪的问题。 Which one is the best way to update UI from another thread. 哪一种是从另一个线程更新UI的最佳方法。 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. 当然,这是针对WinForms的,对于WPF,则是调度程序。 How is the code for WPF? WPF的代码如何?

I'm asking, 'cause, in the past I experienced errors when updating UI from a raised event using both of the options above. 我问,因为过去,使用上述两个选项从引发的事件更新UI时遇到错误。 The kind of error like: "there is no source code available". 这类错误,例如:“没有可用的源代码”。 I assume all of us have seen them :D. 我想我们所有人都看过他们:D。

Thanks, and have a nice day! 感谢,并有一个愉快的一天!

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 在此查看Roy Osherove的博客文章: 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);

The default Action delegate worked 90% of the time: 默认的Action代表90%的时间都在工作:

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

Use [Dispatcher.Invoke(DispatcherPriority, Delegate)] to change the UI from another thread or from background. 使用[Dispatcher.Invoke(DispatcherPriority,Delegate)]可以从另一个线程或后台更改UI。

Step 1 . 步骤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 将以下行放在需要更新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 类型: System.Windows.Threading.DispatcherPriority

The priority, relative to the other pending operations in the Dispatcher event queue, the specified method is invoked. 相对于Dispatcher事件队列中其他未决操作的优先级,将调用指定的方法。

method

Type: System.Delegate 类型: System.Delegate

A delegate to a method that takes no arguments, which is pushed onto the Dispatcher event queue. 一个不带参数的方法的委托,该委托被推送到Dispatcher事件队列中。

Return Value 返回值

Type: System.Object 类型: System.Object

The return value from the delegate being invoked or null if the delegate has no return value. 被调用委托的返回值;如果委托没有返回值,则返回null。

Version Information 版本信息

Available since .NET Framework 3.0 自.NET Framework 3.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. 两者之间并没有真正的有效区别。

如我所见,最好的方法是设置ui元素的属性绑定到的CLR属性。

The first method (BeginInvoke) ensures that the UI update code executes on the same thread that created the control. 第一种方法(BeginInvoke)确保UI更新代码在创建控件的同一线程上执行。 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. 使所有UI更新代码在同一线程上执行可以避免很多线程问题,并允许您使用不一定是线程安全的控件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM