簡體   English   中英

我在 C#(Windows 窗體)中的反應時間測試有問題

[英]Having a problem with my Reaction Time test in C# (Windows Forms)

作為 C# 的新手,我從 1 月份才真正開始使用這種語言進行編碼。 對於我的課程作業,我必須創建一個包含反應時間測試的程序。 我花了大約一周的時間才完全理解代碼應該如何工作,這是我迄今為止所做的:

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 個 FIRST 值,但出於某種原因,我寫了一些可能會導致它再次運行的內容。 調試程序,我覺得和第一次有關系,會記錄時間,但不會算按一次。 老實說,我不知道如何解決這個問題。 希望你們中的一個可以。 我對測試時間的每個 if 語句進行了更改,以添加測試時間。 例如:

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()));
    }
  }
}

不過,您的程序確實存在重大缺陷。 用戶可以在停止按鈕變為綠色之前單擊停止按鈕,當按鈕變為綠色時,它將記錄較早的鼠標單擊。 您應該隱藏按鈕或禁用它,直到反應准備就緒。

ReactionTest()方法在按鈕背景變為綠色並且標簽變為“立即單擊!”后立即返回。 在第一次檢查ButtonPressed標志之前,在第一次ReactionTest()調用之后,用戶沒有機會單擊按鈕 - 因為檢查發生而無需等待(對於用戶輸入)。 所以你是對的,第一次點擊沒有被計算在內。 這就是為什么允許另外 3 次嘗試的原因。

簡單的解決方案是將大部分代碼從button1_Click_1()btnReactionButton_Click()並將async/await添加到ReactionTest()以防止它阻塞 UI 並將btnReactionButton單擊事件排隊,這在ReactionTest()時會錯誤地計為有效點擊ReactionTest()返回。 ButtonPressed標志是不必要的。

    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;
    }

根據@LarsTech 給出的提示,我在適當的時候添加了禁用按鈕。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM