从后台线程更新UI

时间:2011-10-31 19:56:46

标签: c# wpf multithreading user-interface thread-safety

这只是一个奇怪的问题。哪一个是从另一个线程更新UI的最佳方式。首先,这一个:

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

另一方面:

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

或者,有更好的方法吗?

当然这是针对WinForms的,对于WPF,有调度员。 WPF的代码如何?

我问,'因为,过去我在使用上述两个选项从引发的事件更新UI时遇到了错误。类似的错误:“没有可用的源代码”。我假设我们所有人都见过他们:D。

谢谢,祝你有愉快的一天!

6 个答案:

答案 0 :(得分:1)

查看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);

答案 1 :(得分:0)

我通常使用第一个模型,但这只是因为我发现它更清晰。两者之间并没有真正有效的区别。

答案 2 :(得分:0)

我认为最好的方法是设置ui-element属性绑定的CLR属性。

答案 3 :(得分:0)

第一个方法(BeginInvoke)确保UI更新代码在创建控件的同一线程上执行。第二种方法没有。让所有UI更新代码在同一个线程上执行可以避免很多线程问题,并允许您使用不一定是线程安全的控件。

答案 4 :(得分:0)

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

答案 5 :(得分:0)

使用[Dispatcher.Invoke(DispatcherPriority, Delegate)]从其他线程或后台更改用户界面。

第1步。使用以下命名空间

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

第2步。将以下行放在需要更新UI的位置

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

<强>语法

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

<强>参数

     

priority

     

输入:System.Windows.Threading.DispatcherPriority

     

相对于其他待处理操作的优先级   Dispatcher事件队列,调用指定的方法。

     

method

     

输入:System.Delegate

     

一个不带参数的方法的委托,它被推送到   Dispatcher事件队列。

     

返回值

     

输入:System.Object

     

被调用的委托的返回值,如果是,则返回null   代表没有回报价值。

     

版本信息

     

自.NET Framework 3.0起可用