End-to-end error, but not using streams

I keep getting

Cross-thread operation not valid: Control 'keyholderTxt' accessed from a thread other than the thread it was created on. 

on different controls in different forms of the project, and I found it googled and found a lot of answers on how to access materials from different streams, but as far as I know, I do not use any other streams in my project, and change hundreds of possible places in the code will be unmanageable.

This has never happened, only since I added another code that seems unrelated. I include a sample of places where I get errors below, but this has happened in many places around the solution.

 keyholderTxt.Text = "Keyholders Currently In:\r\n \r\n Nibley 1: + keyholders"; 

or this is a better example, as you can see everything that happens from loading a form to an error:

  private void Identification_Load(object sender, System.EventArgs e) { _Timer.Interval = 1000; _Timer.Tick += new EventHandler(_Timer_Tick); _Timer.Start(); txtIdentify.Text = string.Empty; rightIndex = null; SendMessage(Action.SendMessage, "Place your finger on the reader."); if (!_sender.OpenReader()) { this.Close(); } if (!_sender.StartCaptureAsync(this.OnCaptured)) { this.Close(); } } void _Timer_Tick(object sender, EventArgs e) { this.theTime.Text = DateTime.Now.ToString(); } private void OnCaptured(CaptureResult captureResult) { txtIdentify.Clear(); //other stuff after the cross thread error } 

Can things like not closing datareaders cause such an error?

I am using a Windows Forms application.

+4
source share
4 answers

I suspect the culprit is the following:

 if (!_sender.StartCaptureAsync(this.OnCaptured)) 

I don’t know the API you are using, but based on the name, I think that the OnCaptured callback method is called on the worker thread and not on the user interface thread. Therefore, you need to use Invoke to perform the action in the user interface thread:

 private void OnCaptured(CaptureResult captureResult) { if (InvokeRequired) { Invoke(new System.Action(() => OnCaptured(captureResult))); return; } txtIdentify.Clear(); // ... } 
+7
source

Ok, scratch it. I see that you are using System.Windows.Forms.Timer , which, as the comment below points out, is already running in the user interface thread. I thought you were using System.Timers.Timer .

Wrong answer

A timer callback is executed on the threadpool thread. You can execute it in the user interface thread by setting SynchronizingObject :

  _Timer.Interval = 1000; _Timer.Tick += new EventHandler(_Timer_Tick); _Timer.SynchronizingObject = this; _Timer.Start(); 
+3
source

Have you checked the threadbar in VS?

+1
source

The callback from _Timer ( void _Timer_Tick(object sender, EventArgs e) ) occurs in the background thread. Make sure you use System.Windows.Forms.Timer (assuming you use Windows forms) if you want the callback to be in the user interface thread.

As commentators said. Check the thread window in your debugger to see which thread throws an exception.

Alternatively for window forms try

 void _Timer_Tick(object sender, EventArgs e) { this.BeginInvoke(new Action(() => this.theTime.Text = DateTime.Now.ToString())); } 

And for WPF try this

 void _Timer_Tick(object sender, EventArgs e) { this.Dispatcher.BeginInvoke(new Action(() => this.theTime.Text = DateTime.Now.ToString())); } 

And if this not a control or window, and you are in WPF

 void _Timer_Tick(object sender, EventArgs e) { System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() => this.theTime.Text = DateTime.Now.ToString())); } 
+1
source

Source: https://habr.com/ru/post/1499363/


All Articles