Home > Mobile >  Why is this code sending a cross thread operation exception?
Why is this code sending a cross thread operation exception?

Time:09-17

I've been attempting to implement a CPU monitor that updates every two seconds and displays it on a label called "cpu_usage" in WinForms. Unfortunately my code does not appear to work and gives off this error during runtime:

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

So far I've done a little bit of debugging, and have out that the error occurs whenever I try to display the percentage on the "cpu-usage" label, but I am still unable to figure out how to fix this issue. The CPU monitoring code is below:

    public my_form()
    {
        InitializeComponent();

        // Loads the CPU monitor
        cpuCounter = new PerformanceCounter();
        cpuCounter.CategoryName = "Processor";
        cpuCounter.CounterName = "% Processor Time";
        cpuCounter.InstanceName = "_Total";
        InitTimer();
    }

    // Timer for the CPU percentage check routine
    public void InitTimer()
    {
        cpu_timer = new Timer();
        cpu_timer.Elapsed  = new ElapsedEventHandler(cpu_timer_Tick);
        cpu_timer.Interval = 2000;
        cpu_timer.Start();
    }

    // Initates the checking routine
    private void cpu_timer_Tick(object sender, EventArgs e)
    {
        cpu_usage.Text = getCurrentCpuUsage(); // This line causes the exception error.
    }

    // Method to find the CPU resources
    public string getCurrentCpuUsage()
    {
        string value1 = (int)cpuCounter.NextValue()   "%";
        Thread.Sleep(500);
        string value2 = (int)cpuCounter.NextValue()   "%";
        return value2.ToString();
    }

CodePudding user response:

I managed to fix this error by using System.Windows.Forms for the timer, instead of using the System.Timers.Timer namespace. Additionally, I changed my code to use await and async, to make sure that the thread running the user interface is not frozen during the update. The new code is below:

    // Timer for the CPU percentage check routine
    public void InitTimer()
    {
        cpu_timer.Tick  = new EventHandler(cpu_timer_Tick);
        cpu_timer.Interval = 2000; // in miliseconds
        cpu_timer.Start();
    }

    // Initates the checking routine
    private async void cpu_timer_Tick(object sender, EventArgs e)
    {
        Task<string> cpu_task = new Task<string>(getCurrentCpuUsage);
        cpu_task.Start();
        cpu_usage.Text = await cpu_task;
    }

CodePudding user response:

Like others are saying, I believe you want to execute the setting of the text on the UI thread... can try something like this:

    // Initates the checking routine
    private void cpu_timer_Tick(object sender, EventArgs e)
    {
        cpu_usage.Invoke((MethodInvoker)delegate {
            // Running on the UI thread
            cpu_usage.Text = getCurrentCpuUsage();
        });
    }
  • Related