睡眠方法无法正常工作

时间:2014-04-08 11:44:24

标签: c# winforms

好的,我有一个棋盘应用程序。该应用程序在一个组框中有64个面板。这些面板用表达式CHessBoardPanels {x,y)标识。我用它来改变面板的背景颜色。我想在chessPanel.BackGround变为红色和面板变回白色之间有一个小的延迟。(大约1到2秒延迟) 我已经尝试过Sleep功能,但它基本上会锁定应用程序直到任务完成

以下是我尝试的代码:

for (int Row = 7; Row > 3; --Row)
{
    chessBoardPanels[ Column ,Row].BackColor = Color.Red;
    ++Column;
    //Add text to Moves TextBox
    MovesText.AppendFormat("WhtB {0} {1}{2}", ColumnText, RowText, Environment.NewLine);
    MovesTxt.Text = MovesText.ToString();
    ++ColumnText;
    --RowText;
}

//Start White Horizonal Drill
Column = 0;
Thread.Sleep(5000);             //This does not delay proerperly
for (int Row = 7; Row > 4; --Row)
{
    chessBoardPanels[Column, Row].BackColor = Color.White;
    ++Column;
    //Add text to Moves TextBox
    MovesText.AppendFormat("WhtB {0} {1}{2}", ColumnText, RowText, Environment.NewLine);
    MovesTxt.Text = MovesText.ToString();
    ++ColumnText;
    --RowText;
} 

我正在使用.Net framework 4.0,因为Visual Studio 2010不支持4.5

5 个答案:

答案 0 :(得分:5)

这就是睡眠所做的,它会暂停线程。

您需要的是使用Timer控件,并创建一个颜色更改的队列,让定时器控件定期调用事件处理程序,如下所示:

(在你的Form类中):

Timer timer = new Timer();

(在你的Form的构造函数中):

timer.Tick += new EventHandler(timer_Tick);
timer.Interval = 500; // every 1/2 second
timer.Enabled = true;
timer.Start();

然后您的事件处理程序将执行以下操作:

void timer_Tick(object sender, EventArgs e)
{
    // Read a queue, that contains timings
    var nextItem = PeekAtQueue();
    if ((nextItem != null) && (nextItem.WhenToChangeColor <= DateTime.Now))
    {
        var item = TakeFromQueue(); // as opposed to just peeking
        ChangeColor(item);
    }
} 

这是做什么的? (当然这段代码不是100%完整,你必须自己添加队列访问方法,这取决于你想要/可以使用的内容)

  • 看到Sleep()暂时冻结你的应用程序,你需要一个 解决方案,允许您仍然与您的表单进行交互 在延迟之后仍然有延迟和做某事。
  • 所以你 需要使用计时器在以后执行某些操作。计时器 在这个例子中,每1/2秒执行一次,但你可以使用任何一个 你选择的间隔。
  • 点是,因为这个计时器和这个 配置,某个方法 - 事件处理程序 - 被执行 每1/2秒,或您选择的间隔。
  • 那么你能做什么 然后就是,当你想要稍后发生某种颜色变化时 排队描述颜色变化的对象,例如{E5, "red", today at 04:20:30 PM}
  • 由...执行的事件处理程序 计时器每次查看队列中是否有东西,并且 看看它是什么。它检查是否“改变的时刻 颜色“,如排队对象中所述,现在或已经存在 通过。如果是这样,它会改变颜色。如果没有,它将项目留在 队列的顶部,以及下次事件处理程序获取的时间 再次执行(1/2秒后),它将执行相同的检查 试。
  • 完成颜色更改后,将对象取下 队列中。

答案 1 :(得分:0)

请考虑使用Timer类。这应该允许您在不锁定线程的情况下延迟应用程序。

答案 2 :(得分:0)

  

我尝试过Sleep功能,但它基本上锁定了应用程序   直到任务完成

您需要将应用程序的逻辑移动到主(或UI)线程中。如果在Windows事件处理循环被阻止时在主(UI)线程中调用Thread.Sleep,您的应用程序将“冻结”。

你可以使用的东西:

  • 新线程,任务,执行游戏逻辑的后台工作者
  • 计时器
  • 从另一个线程更新GUI

答案 3 :(得分:0)

Sleep将锁定当前线程,这意味着如果它是主UI线程,则不会处理任何用户输入 - 理想情况下,您应该在该点设置沙漏光标。

要做你想做的事情我认为你需要启动一个后台计时器,然后在回调上设置颜色,然后取消计时器。

当计时器正在关闭时,主UI仍然会响应。 您可能还会发现超过1秒的延迟会让用户感觉延迟太长,但计时器周期以毫秒为单位,因此您可以定义更短的延迟。

答案 4 :(得分:-1)

请尝试以下操作:

Task.Run(() => Thread.Sleep(5000)).Wait();