0

我正在尝试为记忆游戏编写 C# 代码。我想首先向查看者展示矩阵(包含 3 个元素),然后是每个元素的多个选项,一次突出显示该单元格。用户必须从答案面板中选择正确的元素。显示答案矩阵(定义为任务)执行此操作。如果我在显示答案任务的 for 循环中放置一个消息框,则输出序列(首先显示的每个元素的显示矩阵、显示答案等)工作正常。我在每个答案显示后单击并等待下一个。它工作正常。但是如果我删除消息框(所以不需要点击),程序在答案显示后停止(对于第一个元素)。有人可以帮我吗?相关的代码部分是:

Mainform{
......declare number of textboxes and lables...for matrix display
}
 In the Buttonclick from the main form:
{
var firstTask = new Task(() => invokedisplaymatrix(MatrixInfoValues));

var secondTask = firstTask.ContinueWith((t) => invokedisplayblankmatrix(MatrixInfoValues));

var thirdTask = secondTask.ContinueWith((t) =>invokedisplayanswermatrix(MatrixInfoValues));

var fourthTask = thirdTask.ContinueWith((t) => invokedDoselection(MatrixInfoValues));

            firstTask.Start();
}
  private void invokedisplaymatrix(object Minfo1)
        {
            lock (this)
            {
                Invoke(new displaymatrixdelegate(displaymatrix), new object[] { Minfo1 });
                Thread.Sleep(2000);
            }

        }

        private void invokedisplayblankmatrix(object Minfo2)
        {
            lock (this)
            {
                Invoke(new displayblankmatrixdelegate(displayblankmatrix), new object[] { Minfo2 });
            }

        }

        private void invokedisplayanswermatrix(object Minfo3)
        {

            lock (this)
            {
                Invoke(new displayanswermatrixdelegate(displayanswermatrix), new object[] { Minfo3 });
                // Invoke(new displaymatrixdelegate(displaymatrix),new object[] {indx});
            }
        }
..Then in the display answer matrix function:

 public void displayanswermatrix(int[] Minfo3)

        {
 foreach (int ind in FilledTextBoxID2)

            {
                foreach (Control c in splitContainer1.Panel1.Controls)
                {
                    if (c is TextBox && c != null)
                    {
                        if ((boxindexL + 1) == FilledTextBoxID2[j])
                        {
                            c.BackColor = Color.OrangeRed;

                        }
                        else
                        {
                            c.BackColor = Color.MediumSpringGreen;
                        }
                       boxindexL = boxindexL + 1;
                    }

                }

                int AnswerLocation = RandomNumber(1, 5);
                int[] answeroptions=excludenumberfromarray(MatrixValues2[j]); //write a function to make random numbers between 1 and 9 excluding MatrixValues2[j]

                foreach (Control c in splitContainer1.Panel2.Controls)
                {
                    if (c is TextBox)
                    {

                        //c.Text = Convert.ToString(boxindexR);
                            //answeroptions[boxindexR]);
                        if ((boxindexR + 1) == AnswerLocation)
                        {
                            c.Text = Convert.ToString(MatrixValues2[j]); //boxindexR = boxindexR - 1;
                        }
                        else
                        {
                            c.Text = Convert.ToString(answeroptions[boxindexR]);
                        }
                       //
                       //}//placing the required number in the randomly selected box
                       boxindexR = boxindexR + 1;
                    }
                 }


                Thread.Sleep(2000);
               MessageBox.Show("hello after one number");
 j = j + 1;
                boxindexR = 0; boxindexL = 0;
            }//end of first foreach

        }//display answer matrix end

如果我评论消息框,界面会在第一个元素显示后休眠。我可以知道这个错误是怎么来的吗?

4

1 回答 1

0

在 UI 线程上休眠绝不是一个好主意 - 这只是将程序标记为无响应。在您的方法完成之前,UI 无法使自己能够为诸如绘制请求之类的事情提供服务 - 但您的方法(通过反复休眠 2 秒)不允许这样做。我怀疑这种MessageBox用法是在代码消息循环之外强制重绘,所以:工作,但出于错误的原因工作。

基本上,如果你有延迟和暂停,你不应该用Sleep- 你应该使用某种形式的Timer. 这将允许您在 2 秒内获得回调,而不是休眠 2 秒,但(重要的是)让应用程序在此期间实际响应消息队列 - 即让它自己绘制。

然而!如果您只是切换到 a Timer,则无法将这些事情作为延续来执行,因为最初的“开始做事”调用在设置第一张图像时只会持续几毫秒。

Task结论:当你只需要一个Timer和一个回调 ( Tick/ Elapsed)时,你已经使用了很多花哨的东西让自己变得聪明:

- is there any more of X to do? 
  - yes: do (a single) X
  - no: is there any more of Y to do? 
    - yes: do (a single) Y
    - no: is there any more of Z to do?
      - yes: do (a single) Z
      - no: stop timer
于 2012-06-07T06:20:43.680 回答