C# 后台工作者冻结了 GUI

C# background worker frozen the GUI

我正在尝试使用后台工作程序连续更新文本标签,但是对于 DoWork,如果不使用循环,它只会执行一次,但是如果使用无限循环,它会冻结 GUI,任何想法解决这个?非常感谢!!!我是 C# 的新手,仍在努力学习。

这是我的代码:

主要形式为:

backgroundWorkerX.DoWork += backgroundWorkerX_DoWork;
backgroundWorkerX.ProgressChanged += backgroundWorkerX_ProgressChanged;
backgroundWorkerX.WorkerReportsProgress = true;
backgroundWorkerX.RunWorkerAsync();

然后:

public void backgroundWorkerX_DoWork(object sender, DoWorkEventArgs e)
{
    X = -(RSSI_PI1_ST1);
    backgroundWorkerX.ReportProgress(X);
}


public void backgroundWorkerX_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    label9.Text = e.ProgressPercentage.ToString();
}

public void backgroundWorkerX_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{

}

[...] if no loop used, it will only execute once

这是预期的行为。它将执行预期的操作,然后调用 RunWorkerCompleted.

[...] but if infinite loop is used, it freezes the GUI.

你的问题中没有循环。所以我会做一个假设,并给你一个有根据的 猜测 它实际上消耗了所有 CPU,因此使 GUI 崩溃。

// I assume that you loop like this somehow.
do 
{
    X = -(RSSI_PI1_ST1);
    backgroundWorkerX.ReportProgress(X);
} while (true);

试着偶尔给"slow it down"加点东西。否则它将尽可能快地 运行 和 运行,因此消耗所有可用的 CPU。请记住,每次您使用 ReportProgress 时,它都会由 GUI 线程呈现。而且这会经常执行并且不会为 GUI 线程留下大量资源来响应其他事情。下面我使用 Thread.Sleep,这将使线程暂停半秒。但请记住,您只想在后台线程中执行此操作。

do 
{
    X = -(RSSI_PI1_ST1);
    backgroundWorkerX.ReportProgress(X);
    Thread.Sleep(500);
} while (true);

我也会考虑换一种方式。如果您确实需要暂停线程,您不妨使用 Timer. Thread.Sleep will lock the thread, and may therefore not be what you really want. From this answer:

Process() // method to be called after regular interval in Timer
{
    // lengthy process, i.e. data fetching and processing etc.

    // here comes the UI update part
    Dispatcher.Invoke((Action)delegate() { /* update UI */ });
}