这是代码冻结当前窗口。如何使这种形式不冻结。
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)
{
}
}
答案 0 :(得分:1)
正如其他人所说,你正在使用UI线程执行无限循环,你应该使用Timer
控件,它是为你正在做的事情而构建的。
答案 1 :(得分:1)
如果您使用.net 4.5,则使用async-await
可以使您的代码受益。使用await
您不必为RunMe
方法启动单独的线程,它将释放您的UI线程以执行其他工作,但会捕获SynchronizationContext以便您不会必须使用Invoke
来更新UI。有关其工作原理,请参阅this blog。
我认为您应该能够像这样重写代码:
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线程中运行很短的时间。
答案 2 :(得分:0)
您应该仅调用调用来更新标签,如下所示:
while(true)
{
if (!InvokeRequired)
{
label2.Text = s.ToString();
}
else
{
Invoke(new Action(()=>{label2.Text = s.ToString();}));
}
s++;
Task.Delay(10000).Wait(10000);
}