C# 从后台线程更新UI

C# 从后台线程更新UI,c#,wpf,multithreading,user-interface,thread-safety,C#,Wpf,Multithreading,User Interface,Thread Safety,这只是一个奇怪的问题。哪种方法是从另一个线程更新UI的最佳方法。首先,这个: private delegate void MyDelegateMethod(); void MyMethod() { if (unknowncontrol.InvokeRequired) { this.BeginInvoke(new MyDelegateMethod(MyMethod)); return; } unknowncontrol.propert

这只是一个奇怪的问题。哪种方法是从另一个线程更新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


谢谢,祝你今天愉快

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

在我看来,最好的方法是设置一个CLR属性,将ui元素的属性绑定到该属性。

查看Roy Osherove的博客文章:

委托无效函数(T);
Func del=委托
{
//UI代码在这里
};
调用(del);

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

默认操作委托在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!");
}
私有无效日志(字符串值)
{
//确认我们在同一个线程上
if(textBox1.invokererequired)
{
//我们不在同一个线程上-调用UI线程
textBox1.Invoke(新操作(日志),值);
返回;
}
//我们在同一个线程上-更新UI
textBox1.Text+=value+“\r\n”;
}
在某些情况下出现私人无效()
{
日志(“发生了什么事!”);
}
用于从其他线程或后台更改UI

步骤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
)
参数

优先级

类型:
System.Windows.Threading.DispatcherPriority

相对于中的其他挂起操作的优先级 在调度程序事件队列中,将调用指定的方法

方法

类型:
System.Delegate

对不带参数的方法的委托,该方法被推送到 调度程序事件队列

返回值

类型:
System.Object

正在调用的委托的返回值,如果 委托没有返回值

版本信息

从.NET Framework 3.0开始提供


你该怎么做就怎么做。如果你想得到反馈,在将来发布实际代码。如果你对某些代码有问题,就发布。我从未见过“没有可用的源代码”错误。如果您是指VS在尝试查看某个框架方法的代码时给出的消息,那么这不是错误。抛出异常的实际消息是重要的一点。从UI线程调用
Control.Invoke()
Control.BeginInvoke()
是否会导致性能下降?我使用第一种模式,因为如果没有必要,它不需要调用调用。
[BrowsableAttribute(false)]
public object Invoke(
  DispatcherPriority priority,
  Delegate method
)