我的C#(Windows窗体)反应时测试有问题
我对C#比较陌生,从一月份起才真正开始使用这种语言进行编码。对于我的课程作业,我必须创建一个包含反应时测试的程序。我花了大约一周的时间来完全理解代码应该如何工作,这就是我迄今为止所做的:我的C#(Windows窗体)反应时测试有问题,c#,winforms,C#,Winforms,我对C#比较陌生,从一月份起才真正开始使用这种语言进行编码。对于我的课程作业,我必须创建一个包含反应时测试的程序。我花了大约一周的时间来完全理解代码应该如何工作,这就是我迄今为止所做的: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Timers;
using System.Threading;
using System.Diagnostics;
namespace WonderWallsApplication
{
public partial class ReactionTimeTestForm : Form
{
Random random = new Random();
Stopwatch stopwatch = new Stopwatch();
int TimesTested = 0;
int ReactionTime1 = 0;
int ReactionTime2 = 0;
int ReactionTime3 = 0;
bool ButtonPressed = false;
int ReactionTime { get; set; }
public ReactionTimeTestForm()
{
InitializeComponent();
btnReactionButton.BackColor = Color.Red;
}
private void button1_Click(object sender, EventArgs e)
{
}
public void button1_Click_1(object sender, EventArgs e)
{
if (TimesTested == 0)
{
ReactionTest();
if (ButtonPressed == true)
{
ReactionTime1 = ReactionTime;
TimesTested = TimesTested + 1;
ButtonPressed = false;
}
else
{
}
}
else if (TimesTested == 1)
{
ReactionTest();
if (ButtonPressed == true)
{
ReactionTime2 = ReactionTime;
TimesTested = TimesTested + 1;
ButtonPressed = false;
}
else
{
}
}
else if (TimesTested == 2)
{
ReactionTest();
if (ButtonPressed == true)
{
ReactionTime3 = ReactionTime;
TimesTested = TimesTested + 1;
ButtonPressed = false;
}
else
{
}
}
else if (TimesTested == 3)
{
MessageBox.Show("Your times were: " + Convert.ToString(ReactionTime1) + ", " + Convert.ToString(ReactionTime2) + ", " + Convert.ToString(ReactionTime3));
}
else
{
}
}
public void btnReactionButton_Click(object sender, EventArgs e)
{
stopwatch.Stop();
btnReactionButton.BackColor = Color.Red;
btnReactionButton.Text = "Your time was " + stopwatch.ElapsedMilliseconds+ "ms milliseconds";
ReactionTime = Convert.ToInt32(stopwatch.ElapsedMilliseconds);
ButtonPressed = true;
}
public void ReactionTest()
{
stopwatch.Reset();
btnReactionButton.Text = "3";
Task.Delay(1000).Wait();
btnReactionButton.Text = "2";
Task.Delay(1000).Wait();
btnReactionButton.Text = "1";
Task.Delay(1000).Wait();
btnReactionButton.Text = "0";
Task.Delay(1000).Wait();
btnReactionButton.Text = "Press this button when it turns green";
Task.Delay(random.Next(3000, 10000)).Wait();
btnReactionButton.Visible = true;
stopwatch.Start();
btnReactionButton.BackColor = Color.Green;
btnReactionButton.Text = "Click Now!";
}
}
}
我的问题是,当我运行代码时,它会运行反应时测试4次,而不是3次。它确实记录了所有前3个值,但出于某种原因,我写了一些东西,可能会导致它再次运行。调试程序时,我认为它与第一次有关,它会记录时间,但不会将其算作一次按下。我真的不知道如何解决这个问题。希望你们中的一个能。我对每个if语句进行了修改,添加了一个timetested语句。例如:
if (TimesTested == 0)
{
ReactionTest();
TimesTested = TimesTested + 1;
if (ButtonPressed == true)
{
ReactionTime1 = ReactionTime;
ButtonPressed = false;
}
else
{
}
}
但所有这些都是它执行了3次测试,但它输出“你的次数是0,x,x”。X只是记录的反应速度的一个数字 我很难理解你的逻辑。下面是一个更简单的代码版本:
Random random = new Random();
Stopwatch stopwatch = new Stopwatch();
List<long> timesTested = new List<long>();
private void buttonStart_Click(object sender, EventArgs e) {
stopwatch.Reset();
for (int i = 4; i > 0; --i) {
btnReactionButton.Text = i.ToString();
Task.Delay(500).Wait();
btnReactionButton.Invalidate();
}
btnReactionButton.Text = "Press this button when it turns green";
Task.Delay(random.Next(3000, 5000)).Wait();
stopwatch.Start();
btnReactionButton.BackColor = Color.Green;
btnReactionButton.Text = "Click Now!";
}
private void btnReactionButton_Click(object sender, EventArgs e) {
if (stopwatch.IsRunning) {
stopwatch.Stop();
timesTested.Add(stopwatch.ElapsedMilliseconds);
btnReactionButton.BackColor = Color.Red;
btnReactionButton.Text = string.Format("Your time was {0} milliseconds",
timesTested[timesTested.Count - 1]);
if (timesTested.Count == 3) {
MessageBox.Show("Your times were: " + String.Join(", ", timesTested.ToArray()));
}
}
}
Random Random=new Random();
秒表秒表=新秒表();
List timesTested=新列表();
私有无效按钮开始单击(对象发送者,事件参数e){
秒表复位();
对于(int i=4;i>0;--i){
btnReactionButton.Text=i.ToString();
Task.Delay(500.Wait();
btnReactionButton.Invalidate();
}
btnReactionButton.Text=“当按钮变绿时按下此按钮”;
Task.Delay(random.Next(30005000)).Wait();
秒表。开始();
btnReactionButton.BackColor=Color.Green;
btnReactionButton.Text=“立即单击!”;
}
私有void btnReactionButton_单击(对象发送者,事件参数e){
if(秒表正在运行){
秒表;
timesTested.Add(秒表时间延迟毫秒);
btnReactionButton.BackColor=Color.Red;
btnReactionButton.Text=string.Format(“您的时间为{0}毫秒”,
timesTested[timesTested.Count-1]);
如果(timesTested.Count==3){
Show(“您的时间是:”+String.Join(“,”,timesTested.ToArray());
}
}
}
不过,您的程序确实存在一个重大缺陷。用户可以在停止按钮变为绿色之前单击它,当按钮变为绿色时,它将记录先前的鼠标单击。您应该隐藏按钮或禁用按钮,直到反应准备就绪。ReactionTest()
方法在按钮背景变为绿色且标签更改为“立即单击”后立即返回。在第一次调用ReactionTest()
之后,在第一次检查ButtonPressed
标志之前,用户没有机会单击按钮,因为检查是在不等待(用户输入)的情况下进行的。所以你是对的,第一次点击不算在内。这就是为什么允许再尝试3次
简单的解决方案是将大部分代码从button1\u Click\u 1()
移动到btnReactionButton\u Click()
,并将async/wait
添加到ReactionTest()
以防止它阻塞UI并将btnReactionButton
单击事件排队,当ReactionTest()
返回时,这些事件将错误地算作有效的单击<代码>按钮按下标志是不必要的
public void button1_Click_1(object sender, EventArgs e)
{
if (TimesTested < 3)
{
ReactionTest();
}
else
{
MessageBox.Show("Your times were: " + Convert.ToString(ReactionTime1) + ", " + Convert.ToString(ReactionTime2) + ", " + Convert.ToString(ReactionTime3));
}
}
public void btnReactionButton_Click(object sender, EventArgs e)
{
btnReactionButton.Enabled = false;
stopwatch.Stop();
btnReactionButton.BackColor = Color.Red;
btnReactionButton.Text = "Your time was " + stopwatch.ElapsedMilliseconds + "ms milliseconds";
ReactionTime = Convert.ToInt32(stopwatch.ElapsedMilliseconds);
if (TimesTested == 0)
{
ReactionTime1 = ReactionTime;
TimesTested = TimesTested + 1;
}
else if (TimesTested == 1)
{
ReactionTime2 = ReactionTime;
TimesTested = TimesTested + 1;
}
else if (TimesTested == 2)
{
ReactionTime3 = ReactionTime;
TimesTested = TimesTested + 1;
}
}
public async void ReactionTest()
{
stopwatch.Reset();
btnReactionButton.Text = "3";
await Task.Delay(1000);
btnReactionButton.Text = "2";
await Task.Delay(1000);
btnReactionButton.Text = "1";
await Task.Delay(1000);
btnReactionButton.Text = "0";
await Task.Delay(1000);
btnReactionButton.Text = "Press this button when it turns green";
await Task.Delay(random.Next(3000, 10000));
btnReactionButton.Visible = true;
stopwatch.Start();
btnReactionButton.BackColor = Color.Green;
btnReactionButton.Text = "Click Now!";
btnReactionButton.Enabled = true;
}
public void按钮1\u单击1(对象发送者,事件参数e)
{
如果(测试时间<3)
{
反应测试();
}
其他的
{
MessageBox.Show(“您的时间是:“+Convert.ToString(ReactionTime1)+”,“+Convert.ToString(ReactionTime2)+”,“+Convert.ToString(ReactionTime3));
}
}
public void btnReactionButton\单击(对象发送者,事件参数e)
{
btnReactionButton.Enabled=false;
秒表;
btnReactionButton.BackColor=Color.Red;
btnReactionButton.Text=“您的时间为”+stopwatch.elapsedmillesons+“毫秒”;
反应时间=转换为32(秒表时间为毫秒);
如果(测试时间==0)
{
反应时间1=反应时间;
测试时间=测试时间+1;
}
否则如果(测试时间==1)
{
反应时间2=反应时间;
测试时间=测试时间+1;
}
否则如果(测试时间==2)
{
反应时间3=反应时间;
测试时间=测试时间+1;
}
}
公共异步void ReactionTest()
{
秒表复位();
btnReactionButton.Text=“3”;
等待任务。延迟(1000);
btnReactionButton.Text=“2”;
等待任务。延迟(1000);
btnReactionButton.Text=“1”;
等待任务。延迟(1000);
btnReactionButton.Text=“0”;
等待任务。延迟(1000);
btnReactionButton.Text=“当按钮变绿时按下此按钮”;
等待任务。延迟(随机。下一步(3000,10000));
btnReactionButton.Visible=true;
秒表。开始();
btnReactionButton.BackColor=Color.Green;
btnReactionButton.Text=“立即单击!”;
btnReactionButton.Enabled=true;
}
根据@LarsTech给出的提示,我添加了在适当的时候禁用按钮的功能。事件处理程序被触发4次的原因是,当窗体首次初始化时,它第一次在WinForms中被调用。您可以通过遵循以下解决方案来抑制额外的调用:我应该遵循哪种解决方案,因为此线程上有许多答案。而且,我不是最能理解你所说的话的人。你能更详细地向我解释一下发生了什么事吗。干杯