El subproceso de llamada no puede acceder a este objeto porque lo posee un subproceso diferente. WPF

Cada vez que actualizo una etiqueta, recibí este error: El hilo de llamada no puede acceder a este objeto porque lo posee un hilo diferente. Traté de invocar pero falló. Estoy usando el formulario 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; } 

Use el método Dispatcher.Invoke .

Ejecuta el delegado especificado sincrónicamente en el hilo al que está asociado el Dispatcher.

también

En WPF, solo el hilo que creó un DispatcherObject puede acceder a ese objeto. Por ejemplo, un hilo de fondo que se separa del hilo principal de la interfaz de usuario no puede actualizar el contenido de un botón que se creó en el hilo de la interfaz de usuario . Para que el subproceso en segundo plano acceda a la propiedad de contenido del botón, el subproceso en segundo plano debe delegar el trabajo en el despachador asociado con el subproceso de interfaz de usuario. Esto se logra usando Invoke o BeginInvoke. Invoke es sincrónico y BeginInvoke es asincrónico. La operación se agrega a la cola de eventos del Dispatcher en DispatcherPriority especificado.

Recibirá el error porque su etiqueta está creada en el hilo de la interfaz de usuario y está intentando modificar su contenido a través de otro hilo. Aquí es donde necesitaría Dispatcher.Invoke.

Echa un vistazo a este artículo Los hilos de WPF crean aplicaciones más receptivas con el despachador

Puede usar Dispatcher para esto. Tu código se convierte en …

 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"); } } )); 

usar Dispatcher.Invoke

Ejemplo

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

Inicié un subproceso no perteneciente a UI y dentro de este hilo también miré un subproceso de interfaz de usuario. Así que mi requisito es como ejecutar un subproceso de interfaz de usuario dentro de un hilo que no sea UI. Al manejar este escenario obtuve la siguiente excepción. “Excepción: el hilo de llamada no puede acceder a este objeto porque lo posee un hilo diferente”.

En este caso, utilicé el método Dispatcher.Invoke del elemento UI de la siguiente manera y funcionó bien.

 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"); } })); } 

Varias sugerencias para usar BeginInvoke, pero no se menciona EndInvoke. La buena práctica es que “cada BeginInvoke tiene un EndInvoke coincidente” y sin duda debe haber alguna protección contra las condiciones de carrera (Piense: ¿qué ocurre con el código BeginInvoke múltiple pero ninguno ha terminado de procesar?)

Es fácil olvidarlo, y he visto este error (y, sí, es un error) tanto en ejemplos de MSDN como en libros publicados en WinForms.