C# 线程调用冻结窗口

本文关键字:窗口 冻结 调用 线程 | 更新日期: 2023-09-27 18:36:02

这是代码冻结当前窗口。如何使这种形式不冻结。

public partial class Form1 : Form
{
    Thread t;
    int s = 0;
    public Form1()
    {
        InitializeComponent();
        label2.Text = "Push the Button";
        button1.Text = "Push me!";
        button1.Click += new EventHandler(button1_Click);
        this.Controls.Add(label2);
        this.Controls.Add(button1);
    }
    void button1_Click(object sender, EventArgs e)
    {
        t = new Thread(new ThreadStart(RunMe));
        t.Start();
    }
    private void RunMe()
    {
            if (!InvokeRequired)
            {
                while(true)
                {
                    label2.Text = s.ToString();
                    s++;
                    Task.Delay(10000).Wait(10000);
                }
            }
            else
            {
                Invoke(new ThreadStart(RunMe));
            }
    }

    private void Form1_Load(object sender, EventArgs e)
    {
    }
}

C# 线程调用冻结窗口

正如其他人所说,您正在使用 UI 线程来执行无限循环,您应该使用 Timer 控件,它正是针对您正在做的事情而构建的。

https://social.msdn.microsoft.com/Forums/windows/en-US/43daf8b2-67ad-4938-98f7-cae3eaa5e63f/how-to-use-timer-control-in-c?forum=winforms

如果您使用的是 .net 4.5,则代码可以从使用 async-await 中受益。使用 await,您不必为 RunMe 方法启动单独的线程,它将释放您的 UI 线程以执行其他工作,但会捕获 SynchronizationContext,因此您不必使用 Invoke 来更新 UI。有关其工作原理,请参阅此博客。

我认为您应该能够像这样重写代码:

async void button1_Click(object sender, EventArgs e)
{ 
    // kicks off the RunMe method and returns
    await RunMe();
}
private Task RunMe()
{
    while(true)
    {
        label2.Text = s.ToString();
        s++;
        await Task.Delay(10000);
    }    
}

尽管有无限while循环,但该方法仅唤醒以更新标签并在 UI 线程中运行很短的时间。

您应该仅调用调用以更新标签,如下所示:

while(true)
{
    if (!InvokeRequired)
    {
        label2.Text = s.ToString();
    }
    else
    {
        Invoke(new Action(()=>{label2.Text = s.ToString();}));
    }
    s++;
    Task.Delay(10000).Wait(10000);
}