【问题标题】:C# Timer (Console Application)C# 计时器(控制台应用程序)
【发布时间】:2017-07-23 06:52:10
【问题描述】:

我正在尝试为测试其员工的服务器创建一个程序,在该程序中,我需要一个计时器来知道他们需要多长时间才能回答所有问题,该程序几乎完成了,我唯一需要的是一个计时器,我需要计时器从 0 开始计数,并在变量“TestFinished”为真时停止。 我找到了这个计时器,我试图让它从“OnTimedEvent”之外更改变量“Seconds”,但我不能。谁能帮帮我?

    class Program
{
    public static void Main()
    {
        System.Timers.Timer aTimer = new System.Timers.Timer();
        aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
        aTimer.Interval = 1000;
        aTimer.Enabled = true;

        int seconds = 0;
        Console.WriteLine("Press \'q\' to quit the sample.");
        while (Console.Read() != 'q') ;
    }

    // Specify what you want to happen when the Elapsed event is raised.
    private static void OnTimedEvent(object source, ElapsedEventArgs e)
    {
     seconds++;
    }
}

【问题讨论】:

标签: c#


【解决方案1】:

简单的方法是把它变成一个字段。

class Program
{
    static int seconds = 0;
    public static void Main()
    {
        System.Timers.Timer aTimer = new System.Timers.Timer();
        aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
        aTimer.Interval = 1000;
        aTimer.Enabled = true;


        Console.WriteLine("Press \'q\' to quit the sample.");
        while (Console.Read() != 'q') ;
    }

    // Specify what you want to happen when the Elapsed event is raised.
    private static void OnTimedEvent(object source, ElapsedEventArgs e)
    {
     seconds++;
    }
}

编辑:感谢@stuartd

【讨论】:

  • 不是一个全局变量,它是一个字段!
【解决方案2】:

1) 要编译您的代码,您必须在类范围内声明静态变量seconds

class Program
{
    private static int seconds = 0;
    public static void Main()
    {
        System.Timers.Timer aTimer = new System.Timers.Timer();
        aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
        aTimer.Interval = 1000;
        aTimer.Enabled = true;

        Console.WriteLine("Press \'q\' to quit the sample.");
        while (Console.Read() != 'q') ;
    }

    // Specify what you want to happen when the Elapsed event is raised.
    private static void OnTimedEvent(object source, ElapsedEventArgs e)
    {
     seconds++;
    }
}

2) 您可以使用StopWatch 来测量经过的时间:

var sw = StopWatch.StartNew();
sw.Stop();
sw.Elapsed.TotalSeconds;

【讨论】:

  • 谢谢,(不要介意这段文字只是为了让我发送消息)
【解决方案3】:

Timer 不是很精确,不应该用来测量时间,而应该用来安排代码定期执行。

您应该改用Stopwatch 来测量时间。这就是它的目的。只需在您要测量的操作之前调用Start(),然后在完成后立即调用Stop()。然后,您可以通过TicksMillisecondsTimeSpan 访问经过的时间。

例如,假设您调用了某种 Test 类来开始测试,您可以执行以下操作,在执行测试之前启动秒表,然后在测试完成:

class StaffTest
{
    public List<QuizItem> QuizItems = new List<QuizItem>();
    public int Score { get; private set; }
    public double ScorePercent => (double)Score / QuizItems.Count * 100;
    public string Grade =>
        ScorePercent < 60 ? "F" :
        ScorePercent < 70 ? "D" :
        ScorePercent < 80 ? "C" :
        ScorePercent < 90 ? "B" : "A";
    public double ElapsedSeconds => stopwatch.Elapsed.TotalSeconds;

    private Stopwatch stopwatch = new Stopwatch();

    public void BeginTest()
    {
        stopwatch.Restart();

        for (int i = 0; i < QuizItems.Count; i++)
        {
            Console.ForegroundColor = ConsoleColor.Green;
            Console.Write($"Question #{i + 1}: ");
            Console.ResetColor();

            if (QuizItems[i].AskQuestion()) Score++;

            Console.WriteLine();
        }

        stopwatch.Stop();
    }
}

为了完整起见,上面引用的QuizItem 只是一个简单的类,您可以用一个问题、一个或多个可能的答案以及正确答案的索引来填充它。然后它知道如何提出问题,得到响应,并返回 true 或 false:

class QuizItem
{
    public string Question;
    public int IndexOfCorrectAnswer;
    public List<string> PossibleAnswers;

    private bool isMultipleChoice => PossibleAnswers.Count() > 1;

    public QuizItem(string question, List<string> possibleAnswers, 
        int indexOfCorrectAnswer)
    {
        // Argument validation
        if (string.IsNullOrWhiteSpace(question))
            throw new ArgumentException(
                "The question cannot be null or whitespace.", 
                nameof(question));

        if (possibleAnswers == null || !possibleAnswers.Any())
            throw new ArgumentException(
                "The list of possible answers must contain at least one answer.",
                nameof(possibleAnswers));

        if (indexOfCorrectAnswer < 0 || indexOfCorrectAnswer >= possibleAnswers.Count)
            throw new ArgumentException(
                "The index specified must exist in the list of possible answers.",
                nameof(indexOfCorrectAnswer));

        Question = question;
        PossibleAnswers = possibleAnswers;
        IndexOfCorrectAnswer = indexOfCorrectAnswer;
    }

    public bool AskQuestion()
    {
        var correct = false;

        Console.WriteLine(Question);

        if (isMultipleChoice)
        {
            for (int i = 0; i < PossibleAnswers.Count; i++)
            {
                Console.WriteLine($"  {i + 1}: {PossibleAnswers[i]}");
            }

            int response;

            do
            {
                Console.Write($"\nEnter answer (1 - {PossibleAnswers.Count}): ");
            } while (!int.TryParse(Console.ReadLine().Trim('.', ' '), out response) ||
                     response < 1 ||
                     response > PossibleAnswers.Count);

            correct = response - 1  == IndexOfCorrectAnswer;
        }
        else
        {
            Console.WriteLine("\nEnter your answer below:");
            var response = Console.ReadLine();
            correct = IsCorrect(response);

        }

        Console.ForegroundColor = correct ? ConsoleColor.Green : ConsoleColor.Red;
        Console.WriteLine(correct ? "Correct" : "Incorrect");
        Console.ResetColor();

        return correct;
    }

    public bool IsCorrect(string answer)
    {
        return answer != null &&
            answer.Equals(PossibleAnswers[IndexOfCorrectAnswer],
            StringComparison.OrdinalIgnoreCase);
    }
}

有了这些类,管理测试变得非常容易。您唯一需要做的就是创建一些QuizItem 对象,然后调用test.BeginTest();。剩下的工作就完成了,包括获取经过的时间。

例如:

static void Main(string[] args)
{
    // Create a new test
    var test = new StaffTest
    {
        QuizItems = new List<QuizItem>
        {
            new QuizItem("What it the capital of Washington State?", 
                new List<string> {"Seattle", "Portland", "Olympia" }, 2),
            new QuizItem("What it the sum of 45 and 19?", 
                new List<string> {"64"}, 0),
            new QuizItem("Which creature is not a mammal?", 
                new List<string> {"Dolphin", "Shark", "Whale" }, 1)
        }
    };

    Console.Write("Press any key to start the test...");
    Console.ReadKey();
    Console.ForegroundColor = ConsoleColor.Yellow;
    Console.WriteLine($"\n\n(Test started at {DateTime.Now})\n");
    Console.ResetColor();

    test.BeginTest();

    Console.ForegroundColor = ConsoleColor.Yellow;
    Console.WriteLine($"(Test ended at {DateTime.Now})\n");
    Console.ResetColor();

    Console.WriteLine($"Thank you for taking the test.\n");
    Console.WriteLine($"You scored ................ {test.Score} / {test.QuizItems.Count}");
    Console.WriteLine($"Your percent correct is ... {test.ScorePercent.ToString("N0")}%");
    Console.WriteLine($"Your grade is ............. {test.Grade}");
    Console.WriteLine($"The total time was ........ {test.ElapsedSeconds.ToString("N2")} seconds");

    Console.Write("\nDone!\nPress any key to exit...");
    Console.ReadKey();
}

输出

【讨论】:

  • 我已经测试了秒表并将其与计时器进行了比较,并且有很大的不同,你是对的,计时器更慢,而且根本不准确。感谢您的详细回答和帮助。
猜你喜欢
  • 2012-06-03
  • 2011-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-05
相关资源
最近更新 更多