System.InvalidOperationException:“调用线程无法访问此对象,因为另一个线程拥有该对象。”
正确的做法是使用Dispatcher
Dispatcher简单暴力,适合小工作量的修改一些界面内容
长期后台工作应该考虑使用BackgroundWorker
,有很多相关功能库
Task t = new Task(() =>
//wrong
//NameLabel.Content = "我用非UI线程修改NameLabel的文字,失败了";
NameLabel.Dispatcher.Invoke(new Action(delegate
NameLabel.Content = "我用UI线程修改了NameLabel的文字";
Thread.Sleep(5000);
this.Dispatcher.Invoke(new Action(() =>
NameLabel.Content = "我用UI线程修改了NameLabel的文字-2";
Thread.Sleep(5000);
this.Dispatcher.BeginInvoke(new Action(() =>
NameLabel.Content = "我用UI线程修改了NameLabel的文字-3";
t.Start();
Dispatcher使用一个专用的 UI 线程来完成界面的操作和更新,这个线程会关联一个唯一的WPF Dispatcher 对象,用于调度按优先顺序排列的工作项队列。Application.Run() 实际上就是对 Dispatcher.Run() 的间接调用。
WPF Dispatcher通过循环来处理工作项队列,这个循环通常被成为 "帧 (DispatcherFrame)"。Dispatcher.Run() 创建并启动这个帧,这也是 Application.Run() 启动消息循环的最终途径。