简体   繁体   English

C#背景工作者冻结了GUI

[英]C# background worker frozen the GUI

I'm trying to use background worker to update a text label continuously, but for DoWork, if no loop used, it will only execute once, but if infinite loop is used, it freezes the GUI, any idea to solve this? 我正在尝试使用后台工作程序连续更新文本标签,但是对于DoWork,如果不使用循环,它将仅执行一次,但是如果使用无限循环,它将冻结GUI,您有解决此问题的想法吗? Really appreciate!!! 万分感激!!! I'm pretty new to C# and still trying to learn. 我是C#的新手,但仍在尝试学习。

Here's my code: 这是我的代码:

This in the main form: 其主要形式为:

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

Then: 然后:

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 [...]如果不使用循环,它将仅执行一次

This is the expected behavior. 这是预期的行为。 It will do the thing it's expected and then call RunWorkerCompleted . 它将执行预期的操作,然后调用RunWorkerCompleted

[...] but if infinite loop is used, it freezes the GUI. [...]但如果使用无限循环,它将冻结GUI。

You don't present a loop in your question. 您不会在问题中出现循环。 So I'll make an assumption and will give you an educated guess that it actually consumes all the CPU, and therefore crashes the GUI. 因此,我将做一个假设,并给您一个有根据的猜测 ,即它实际上消耗了所有CPU,从而导致GUI崩溃。

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

Try to add something to "slow it down" once in a while. 尝试不时添加一些东西来“减慢速度” Otherwise it will just run and run as fast as possible, and therefore consume all the CPU available. 否则,它将仅运行并尽可能快地运行,因此会消耗所有可用的CPU。 Remember that everytime you use ReportProgress it will be rendered by the GUI-thread. 请记住,每次使用ReportProgress ,它将由GUI线程呈现。 And this will execute very often and not leave a lot of resources for the GUI thread to respond to other things. 这将非常频繁地执行,并且不会为GUI线程留下很多资源来响应其他事情。 Below I use Thread.Sleep , which will pause the thread for half a second. 在下面,我使用Thread.Sleep ,它将暂停线程半秒钟。 But remember that you will only want to do this in a background thread. 但是请记住,您只想在后台线程中执行此操作。

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

I would also consider doing this another way. 我也将考虑以另一种方式进行此操作。 If you actually have the need of pausing the thread, you might as well do it with a Timer . 如果确实需要暂停线程,则最好使用Timer Thread.Sleep will lock the thread, and may therefore not be what you really want. Thread.Sleep将锁定线程,因此可能不是您真正想要的。 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 */ });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM