Windows Forms | Illegal cross-thread operation - how do I handle it?

I'm yet a beginner in C#. I do know the sole basics of object oriented programming, however I'm not quite skilled in the more complex stuff of Windows Forms (I do know the basics). I found something about a Delegate function, I'm not quite sure how to use that.
I need to solve this invalid cross-thread operation I got, I wasn't aware of that. However I don't know how to do it. How do I create appropriate delegate function? How do I invoke it to set a value of a textbox across the threads?
This is the exception I got:
And this is my Form1.cs
file:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Klikačka
{
public partial class MainForm : Form
{
private Microsoft.Win32.RegistryKey registry;
public MainForm()
{
if (Microsoft.Win32.Registry.CurrentUser.GetSubKeyNames().Contains(@"SOFTWARE\Klikacka\Nastaveni"))
{
registry = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Klikacka\Nastaveni");
} else
{
registry = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(@"SOFTWARE\Klikacka\Nastaveni");
}
InitializeComponent();
}
private void checkRegistry(Object source, System.Timers.ElapsedEventArgs e)
{
string pocitadlo1_str = (string)registry.GetValue("pocitadlo1");
string pocitadlo2_str = (string)registry.GetValue("pocitadlo2");
string pocitadlo3_str = (string)registry.GetValue("pocitadlo3");
string pocitadlo4_str = (string)registry.GetValue("pocitadlo4");
string pocitadlo5_str = (string)registry.GetValue("pocitadlo5");
string pocitadlo6_str = (string)registry.GetValue("pocitadlo6");
string pocitadlo7_str = (string)registry.GetValue("pocitadlo7");
string pocitadlo8_str = (string)registry.GetValue("pocitadlo8");
string pocitadlo9_str = (string)registry.GetValue("pocitadlo9");
DateTime pocitadlo1, pocitadlo2, pocitadlo3, pocitadlo4, pocitadlo5;
DateTime pocitadlo6, pocitadlo7, pocitadlo8, pocitadlo9;
if (DateTime.TryParse(pocitadlo1_str, out pocitadlo1))
{
checkCounter(1, pocitadlo1, counter1);
}
if (DateTime.TryParse(pocitadlo2_str, out pocitadlo2))
{
checkCounter(2, pocitadlo2, counter2);
}
if (DateTime.TryParse(pocitadlo3_str, out pocitadlo3))
{
checkCounter(3, pocitadlo3, counter3);
}
if (DateTime.TryParse(pocitadlo4_str, out pocitadlo4))
{
checkCounter(4, pocitadlo4, counter4);
}
if (DateTime.TryParse(pocitadlo5_str, out pocitadlo5))
{
checkCounter(5, pocitadlo5, counter5);
}
if (DateTime.TryParse(pocitadlo6_str, out pocitadlo6))
{
checkCounter(6, pocitadlo6, counter6);
}
if (DateTime.TryParse(pocitadlo7_str, out pocitadlo7))
{
checkCounter(7, pocitadlo7, counter7);
}
if (DateTime.TryParse(pocitadlo8_str, out pocitadlo8))
{
checkCounter(8, pocitadlo8, counter8);
}
if (DateTime.TryParse(pocitadlo9_str, out pocitadlo9))
{
checkCounter(9, pocitadlo9, counter9);
}
}
private void checkCounter(int num, DateTime counter, TextBox box)
{
DateTime now = DateTime.Now;
TimeSpan diff = now - counter;
long elapsed_days = (long)diff.TotalDays;
long current_counter_value, new_counter_value;
// Provede kontrolu počítadla
current_counter_value = long.Parse(box.Text);
new_counter_value = current_counter_value - elapsed_days;
if (elapsed_days == 0)
return; // Pokud neuplynul den, nedělej nic
updateRegistry("pocitadlo" + num);
box.Text = new_counter_value.ToString();
/*switch (num)
{
case 1:
// provede kontrolu počítadla č.1
current_counter_value = long.Parse(counter1.Text);
new_counter_value = current_counter_value - elapsed_days;
registry.SetValue("pocitadlo1", now.ToString());
counter1.Text = new_counter_value.ToString();
break;
case 2:
// provede kontrolu počítadla č.2
current_counter_value = long.Parse(counter2.Text);
new_counter_value = current_counter_value - elapsed_days;
registry.SetValue("pocitadlo2", now.ToString());
counter2.Text = new_counter_value.ToString();
break;
case 3:
// provede kontrolu počítadla č.3
current_counter_value = long.Parse(counter3.Text);
new_counter_value = current_counter_value - elapsed_days;
registry.SetValue("pocitadlo3", now.ToString());
counter3.Text = new_counter_value.ToString();
break;
case 4:
// provede kontrolu počítadla č.4
current_counter_value = long.Parse(counter4.Text);
new_counter_value = current_counter_value - elapsed_days;
registry.SetValue("pocitadlo4", now.ToString());
counter4.Text = new_counter_value.ToString();
break;
case 5:
// provede kontrolu počítadla č.5
current_counter_value = long.Parse(counter5.Text);
new_counter_value = current_counter_value - elapsed_days;
registry.SetValue("pocitadlo5", now.ToString());
counter5.Text = new_counter_value.ToString();
break;
case 6:
// provede kontrolu počítadla č.6
current_counter_value = long.Parse(counter6.Text);
new_counter_value = current_counter_value - elapsed_days;
registry.SetValue("pocitadlo6", now.ToString());
counter6.Text = new_counter_value.ToString();
break;
case 7:
// provede kontrolu počítadla č.7
current_counter_value = long.Parse(counter7.Text);
new_counter_value = current_counter_value - elapsed_days;
registry.SetValue("pocitadlo7", now.ToString());
counter7.Text = new_counter_value.ToString();
break;
case 8:
// provede kontrolu počítadla č.8
current_counter_value = long.Parse(counter8.Text);
new_counter_value = current_counter_value - elapsed_days;
registry.SetValue("pocitadlo8", now.ToString());
counter8.Text = new_counter_value.ToString();
break;
case 9:
// provede kontrolu počítadla č.9
current_counter_value = long.Parse(counter9.Text);
new_counter_value = current_counter_value - elapsed_days;
registry.SetValue("pocitadlo9", now.ToString());
counter9.Text = new_counter_value.ToString();
break;
default:
// zadáno neplatné počítadlo
throw new Exception("Zadáno neplatné počítadlo!");
}*/
}
private void updateRegistry(string property)
{
DateTime now = DateTime.Now;
registry.SetValue(property, now.ToString());
}
private void MainForm_Load(object sender, EventArgs e)
{
System.Timers.Timer timer = new System.Timers.Timer();
timer.Interval = 100;
timer.Elapsed += checkRegistry;
timer.AutoReset = true;
timer.Enabled = true;
}
private void aboutButton_Click(object sender, EventArgs e)
{
AboutBox dialog = new AboutBox();
dialog.ShowDialog();
}
private void counter1_Click(object sender, EventArgs e)
{
updateRegistry("pocitadlo1");
counter1.Text = "10";
}
private void counter2_Click(object sender, EventArgs e)
{
updateRegistry("pocitadlo2");
counter2.Text = "10";
}
private void counter3_Click(object sender, EventArgs e)
{
updateRegistry("pocitadlo3");
counter3.Text = "10";
}
private void counter4_Click(object sender, EventArgs e)
{
updateRegistry("pocitadlo4");
counter4.Text = "10";
}
private void counter5_Click(object sender, EventArgs e)
{
updateRegistry("pocitadlo5");
counter5.Text = "10";
}
private void counter6_Click(object sender, EventArgs e)
{
updateRegistry("pocitadlo6");
counter6.Text = "10";
}
private void counter7_Click(object sender, EventArgs e)
{
updateRegistry("pocitadlo7");
counter7.Text = "10";
}
private void counter8_Click(object sender, EventArgs e)
{
updateRegistry("pocitadlo8");
counter8.Text = "10";
}
private void counter9_Click(object sender, EventArgs e)
{
updateRegistry("pocitadlo9");
counter9.Text = "10";
}
}
}
The form looks like this, btw:
Can please anyone give me step-by-step guide on how to create a Delegate function? What do I need to know before I try to invoke necessary changes? Specific example for a TextBox
text parameter would be very useful.
1 additional answer
Sort by: Most helpful
-
Viorel 94,761 Reputation points
2021-02-26T12:17:58.467+00:00 In forms application you can usually use another timer: System.Forms.Timer (maybe with some code adjustments).
If you want to continue using System.Timers.Timer, or try a quick fix, then add this line:
timer. SynchronizingObject = this;