为什么这段代码会发送跨线程操作异常?
Why is this code sending a cross thread operation exception?
我一直在尝试实现一个 CPU 监视器,它每两秒更新一次并将其显示在 WinForms 中名为“cpu_usage”的标签上。不幸的是,我的代码似乎无法正常工作,并在运行时发出此错误:
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监控代码如下:
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();
}
我设法通过使用 System.Windows.Forms
作为计时器来修复此错误,而不是使用 System.Timers.Timer
命名空间。此外,我更改了我的代码以使用 await 和 async,以确保线程 运行 用户界面在更新期间不会被冻结。新代码如下:
// 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;
}
就像其他人所说的那样,我相信你想在 UI 线程上执行文本设置......可以尝试这样的事情:
// 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();
});
}
我一直在尝试实现一个 CPU 监视器,它每两秒更新一次并将其显示在 WinForms 中名为“cpu_usage”的标签上。不幸的是,我的代码似乎无法正常工作,并在运行时发出此错误:
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监控代码如下:
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();
}
我设法通过使用 System.Windows.Forms
作为计时器来修复此错误,而不是使用 System.Timers.Timer
命名空间。此外,我更改了我的代码以使用 await 和 async,以确保线程 运行 用户界面在更新期间不会被冻结。新代码如下:
// 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;
}
就像其他人所说的那样,我相信你想在 UI 线程上执行文本设置......可以尝试这样的事情:
// 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();
});
}