简体   繁体   中英

C# Timer (Console Application)

i am trying to create a program for a server that tests their staff members, in the program i need a timer to know how long it took them to answer all the questions, the program is almost done , the only thing i need is a timer, i need the timer to count from 0 and stop when the variable "TestFinished" is true. i found this timer and im trying to make it change the variable "Seconds" from outside the "OnTimedEvent" but i cant. anyone can help me?

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

Simple way is to make it a field.

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

EDIT: Thanks to @stuartd

1) To make your code compile you have to declare static variable seconds in class scope:

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) You may use StopWatch to measure elapsed time:

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

A Timer is not very exact and should not be used to measure time, but should instead be used to schedule code to be executed in regular intervals.

You should use a Stopwatch to measure time instead. That's what it was made for. Just call Start() before the operation you want to measure, and then Stop() as soon as it's done. You can then access the elapsed time in terms of Ticks , Milliseconds , or a TimeSpan .

For example, assuming you have some sort of Test class that you call to start the test, you could do something like below, where you start the stopwatch just before administering the test, and then stop it as soon as the test completes:

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

For completeness, the QuizItem referenced above is just a simple class that you can populate with a question, one or more possible answers, and the index of the correct answer. Then it knows how to ask the question, get the response, and return true or 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);
    }
}

With these classes, it makes administering the test pretty easy. The only thing you have to do is create some QuizItem objects and then call test.BeginTest(); . The rest of the work is done, including getting the elapsed time.

For example:

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

Output

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM