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