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)
{
}
}
正如其他人所说,您正在使用 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);
}