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

Marek Poláček 21 Reputation points
2021-02-26T11:48:03.087+00:00

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:
72484-image.png

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:
72447-image.png

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.

Windows Forms
Windows Forms
A set of .NET Framework managed libraries for developing graphical user interfaces.
1,838 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,307 questions
{count} votes

Accepted answer
  1. Castorix31 81,831 Reputation points
    2021-02-26T12:00:39.673+00:00

1 additional answer

Sort by: Most helpful
  1. Viorel 112.5K 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;