2015-03-02 156 views
0

我正在制作一个记忆游戏。每当用户点击一个按钮,图像就会显示出来。然后用户必须点击另一个按钮。如果两个图像匹配,则按钮将被刻度标记替换。如果没有,那么用户需要1秒的时间才能记住图像位置。然后再次隐藏图像并显示按钮。 我通过 Thread.sleep代码(1000)C#:如何在不停止程序执行的情况下执行线程

我已经嵌入在其持续时间是30秒的游戏倒数计时器执行1秒的间隙。我已经放置了一个标签,显示每个时钟刻度的30秒倒计时。


现在的实际问题是,只要调用Thread.Sleep(1000),计时器就会暂停。 1秒后,它恢复。我希望这个计时器不管线程执行。请帮忙。

+5

的解决方案是*不阻止UI线程*而不是阻止UI线程并使UI仍然响应。 – Servy 2015-03-02 17:34:54

+2

如果你有计时器,你为什么在第一时间调用Thread.Sleep(1000)?请张贴一些代码给我们看看。 – JNYRanger 2015-03-02 17:35:04

+2

,因为该计时器与您正在执行它的位置在同一个线程上,这也是Thread.Sleep存在的地方 - 这是问题所在。你需要分开2 ....当你正在做Thread.Sleep的时候,你阻塞了你的主(在这种情况下是UI)线程。显示您目前正在使用的代码! – 2015-03-02 17:35:12

回答

2

有点难以理解你在问什么,所以如果我误解了你的道歉,但我想你问的是如何在不阻塞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); 
} 
相关问题