有点难以理解你在问什么,所以如果我误解了你的道歉,但我想你问的是如何在不阻塞UI线程的情况下在新线程上使用计时器更新UI?答案是,你不能在一个线程中更新一个UI控件,而不是创建一个UI控件。相反,你必须创建一个委托来为你做。
所以,这给你一个例外,因为在计时器结束回调UpdateText
计时器线程上执行,而不是在主UI线程:
private void button1_Click(object sender, EventArgs e)
{
System.Threading.Timer timer = new System.Threading.Timer(UpdateText, null, 1000, System.Threading.Timeout.Infinite);
}
public void UpdateText(object state)
{
this.textBox1.AppendText("Ouch!" + Environment.NewLine);
}
然而,这种按预期工作:当你点击按钮,一秒钟之后,单词“哎呀!”出现在文本框中。这是因为,使用在与MethodInvoker
代表TextBox控件BeginInvoke
方法的使委托给拥有该控制(即,主UI线程)在线程上执行,而不是定时器线程上:
private void button1_Click(object sender, EventArgs e)
{
System.Threading.Timer timer = new System.Threading.Timer(UpdateText, null, 1000, System.Threading.Timeout.Infinite);
}
public void UpdateText(object state)
{
MethodInvoker action = delegate
{
this.textBox1.AppendText("Ouch!" + Environment.NewLine);
};
this.textBox1.BeginInvoke(action);
}
的解决方案是*不阻止UI线程*而不是阻止UI线程并使UI仍然响应。 – Servy 2015-03-02 17:34:54
如果你有计时器,你为什么在第一时间调用Thread.Sleep(1000)?请张贴一些代码给我们看看。 – JNYRanger 2015-03-02 17:35:04
,因为该计时器与您正在执行它的位置在同一个线程上,这也是Thread.Sleep存在的地方 - 这是问题所在。你需要分开2 ....当你正在做Thread.Sleep的时候,你阻塞了你的主(在这种情况下是UI)线程。显示您目前正在使用的代码! – 2015-03-02 17:35:12