我正在尝试为内存游戏编写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
如果我对消息框进行评论,则在第一个元素显示后,界面会在那里休眠。 我可以知道这个错误是怎么来的吗?
答案 0 :(得分:0)
在UI线程上睡觉是从不一个好主意 - 这只会将程序标记为无响应。在您的方法完成之前,UI无法使自己可用于绘制请求之类的东西 - 但是您的方法(通过一遍又一遍地睡眠2秒)不允许。我怀疑MessageBox
用法强制在代码消息循环之外重绘,所以:工作,但工作原因错误。
基本上,如果您有延迟和暂停,则不应该使用Sleep
来处理 - 您应该使用某种形式的Timer
。这将允许您在2秒内获得回调,而不是睡眠2秒,但(重要的是)让应用程序实际上在过渡期间响应消息队列 - 即让它自己绘制。 / p>
然而!如果您只是切换到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