【发布时间】:2016-09-07 20:38:19
【问题描述】:
我应该如何编辑存在于 C# 任务之外的 WPF 数据?我已经使用标准 WPF 模板定义了一个 UI。网格仅包含:
<TextBlock x:Name="myTextBox" Text="Original Text" />
在我的代码中:
using System.Threading.Tasks;
using System.Windows;
namespace UpdateGUI
{
public partial class MainWindow : Window
{
private int myInt;
public MainWindow()
{
InitializeComponent();
myInt = 0;
Task.Factory.StartNew(() =>
{
myInt++;
myTextBox.Text = "New Text";
});
}
}
}
这会引发以下异常:
调用线程无法访问此对象,因为另一个线程拥有它。
哪个线程拥有 myTextBox?为什么我在编辑 myInt 时看不到此错误?
【问题讨论】:
-
只有 UI 线程应该更新 UI 元素。如果另一个线程需要更新 UI,它应该要求 UI 线程去做。一种方法是通过Dispatcher class。
-
或者你可以使用双向绑定机制。将文本框绑定到模型上的属性,然后您可以更新模型,模型会自动更新文本框。
-
您的示例代码的问题在于它过于简单,没有任何理由需要启动另一个线程。如果您有更具体的需求来解释为什么生成线程,也许我们可以更具体地指导您。
-
您需要使用异步等待或使用 Dispatcher 调用将 UI 更新调用回 UI 线程。这被标记为欺骗,这是真的。但链接到 WinForm 解决方案,该解决方案不会延续到 WPF。欺骗答案应链接到 WPF 解决方案。
-
@rmcshry WPF 中的数据绑定是自切片面包以来最好的东西。值得花时间学习使用它。
标签: c# wpf multithreading