调用线程无法访问此对象,因为另一个线程拥有它.WPF

每当我刷新标签时,我都会收到此错误: 调用线程无法访问此对象,因为另一个线程拥有它。 我试图调用,但它失败了。 我正在使用WPF表格。

delegate void lostfocs(string st); private void imgPayment_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { Thread t = new Thread(modi); t.Start(); } void modi() { try { label1.Content = "df"; } catch { lostfocs ld = new lostfocs(up); // ld.Invoke("df"); object obj=new object(); ld.Invoke("sdaf"); } } void up(string st) { label1.Content = st; } 

使用Dispatcher.Invoke方法。

在与Dispatcher关联的线程上同步执行指定的委托。

在WPF中,只有创建DispatcherObject的线程才能访问该对象。 例如, 从主UI线程分离出来后台线程无法更新在UI线程上创建的Button的内容 。 为了让后台线程访问Button的Content属性,后台线程必须将工作委托给与UI线程关联的Dispatcher。 这是通过使用Invoke或BeginInvoke来完成的。 Invoke是同步的,Be​​ginInvoke是异步的。 该操作将添加到指定DispatcherPriority的Dispatcher的事件队列中。

您收到错误是因为您的标签是在UI线程上创建的,并且您正在尝试通过另一个线程修改其内容。 这是您需要Dispatcher.Invoke的地方。

看看这篇文章WPF Threads使用Dispatcher构建更多响应式应用程序

您可以使用Dispatcher。 你的代码变成……

 private void imgPayment_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(() => { try { label1.Content = "df"; } catch { lostfocs ld = new lostfocs(up); // ld.Invoke("df"); object obj=new object(); ld.Invoke("sdaf"); } } )); 

使用Dispatcher.Invoke

  void modi() { if(!Dispatcher.CheckAccess()) { Dispatcher.Invoke( ()=>label1.Content = "df",DispatcherPriority.Normal); } else { label1.Content = "df"; } } 

我启动了一个非UI线程,在这个线程中我也盯着一个UI线程。 所以我的要求就像在非UI线程中运行UI线程。 处理此方案时,我得到以下exception。 “exception:调用线程无法访问此对象,因为不同的线程拥有它。”

在这种情况下,我使用了UI元素的Dispatcher.Invoke方法,如下所示,它运行良好。

 if (m_contextWindow == null) { System.Threading.Thread newWindowThread = new System.Threading.Thread(new ThreadStart( () => { // Create and show the Window m_contextWindow = new ContextWindow(); m_contextWindow.DataContext = this; m_contextWindow.Show(); // Start the Dispatcher Processing System.Windows.Threading.Dispatcher.Run(); })); // Set the apartment state newWindowThread.SetApartmentState(ApartmentState.STA); // Make the thread a background thread newWindowThread.IsBackground = true; // Start the thread newWindowThread.Start(); } else { this.m_contextWindow.Dispatcher.Invoke(new ThreadStart(() => { m_contextWindow.DataContext = this; if (m_contextWindow.Visibility == System.Windows.Visibility.Collapsed || m_contextWindow.Visibility == System.Windows.Visibility.Hidden) m_contextWindow.Visibility = System.Windows.Visibility.Visible; })); } 
 private void imgPayment_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(() => { try { label1.Content = "df"; } catch { lostfocs ld = new lostfocs(up); object obj = new object(); ld.Invoke("sdaf"); } })); } 

有几个使用BeginInvoke的建议,但没有提到EndInvoke。 好的做法是’每个BeginInvoke都有一个匹配的EndInvoke’,当然需要有一些防范竞争条件的保护(想想:多个BeginInvoke代码会发生什么,但是还没有完成处理?)

它很容易忘记,我在MSDN示例和WinForms上发布的书籍中都看到了这个错误(是的,这一个错误)