I keep getting
Cross-thread operation not valid: Control 'keyholderTxt' accessed from a thread other than the thread it was created on.
on various controls on various forms in a project, and I have googled it and found lot's of responses about how to access stuff from various threads, but as far as I know, i'm not using any other threads in my project, and to change the hundreds of possible places in the code would be unmanageable.
It never used to happen, only since I added various code that seems unrelated. I include a sample of places where I get the errors below, but it has occurred in so many places all over the solution.
keyholderTxt.Text = "Keyholders Currently In:\r\n \r\n Nibley 1: + keyholders";
or this, a better example, as you can see everything that happends from the form loading until the 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 this kind of error?
I am using a Windows Forms Application.
I suspect the culprit is this:
if (!_sender.StartCaptureAsync(this.OnCaptured))
I don't know the API you're using, but based on the name, I think the callback method (OnCaptured
) is called on a worker thread, not the UI thread. So you need to use Invoke to perform the action on the UI thread:
private void OnCaptured(CaptureResult captureResult)
{
if (InvokeRequired)
{
Invoke(new System.Action(() => OnCaptured(captureResult)));
return;
}
txtIdentify.Clear();
// ...
}
Okay, scratch this. I see you're using System.Windows.Forms.Timer
which, as the comment below mentions, already executes on the UI thread. I was thinking you were using System.Timers.Timer
.
The timer callback is executing on a threadpool thread. You can make it execute on the UI thread by setting the SynchronizingObject:
_Timer.Interval = 1000;
_Timer.Tick += new EventHandler(_Timer_Tick);
_Timer.SynchronizingObject = this;
_Timer.Start();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With