首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么这段代码会发送一个跨线程操作异常?

为什么这段代码会发送一个跨线程操作异常?
EN

Stack Overflow用户
提问于 2021-09-04 18:16:52
回答 2查看 60关注 0票数 0

我一直在尝试实现一个每两秒更新一次的CPU监视器,并将其显示在WinForms中名为"cpu_usage“的标签上。不幸的是,我的代码似乎不能正常工作,并在运行时显示以下错误:

代码语言:javascript
复制
 System.InvalidOperationException: 'Cross-thread operation not valid: Control 'cpu_usage' accessed from a thread other than the thread it was created on.'

到目前为止,我已经做了一些调试,并且发现每当我试图在"cpu-usage“标签上显示百分比时,都会出现错误,但我仍然无法弄清楚如何解决这个问题。CPU监控代码如下:

代码语言:javascript
复制
    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();
    }
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-09-04 19:35:42

我通过使用计时器的System.Windows.Forms,而不是使用System.Timers.Timer命名空间,设法修复了这个错误。此外,我将代码更改为使用await和async,以确保运行用户界面的线程在更新期间不会被冻结。新代码如下:

代码语言:javascript
复制
    // 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;
    }
票数 1
EN

Stack Overflow用户

发布于 2021-09-04 22:39:02

就像其他人说的,我相信你想要在UI线程上执行文本的设置……可以尝试如下所示:

代码语言:javascript
复制
    // 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();
        });
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69057898

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档