我刚刚注意到我可以从另一个线程更新绑定源,并且它可以正常工作。
所以我准备了下面的演示,我的问题是:
- 为什么绑定起作用?为什么来自另一个线程的通知不会抛出异常?
- 像这样从另一个线程更新源是否“合法”?
我一直在使用并告诉其他人使用Dispatcher.Invoke
,但也许我只是不知道某些东西?或者说绑定总是保证在UI线程中更新其目标或类似的操作吗?
<TextBox x:Name="textBox" Text="{Binding Text}" />
public partial class MainWindow : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public string Text { get; set; }
public MainWindow()
{
InitializeComponent();
DataContext = this;
Task.Run(() =>
{
Thread.Sleep(3000); // just wait long enough to ensure window is shown
// works
Text = "123";
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Text)));
// will crash with
// System.InvalidOperationException: 'The calling thread cannot access this object because a different thread owns it'
textBox.Text = "123";
});
}
}
Add()
方法)绑定的ObservableCollection<T>
将确实引发(不同的)异常。分配一个新的实例或者如果它是未绑定的则可以工作。有趣的是,有什么样的证据表明可以在任何(即非UI)线程中执行分配操作? - Sinatr