Timer 不是很精确,不应该用来测量时间,而应该用来安排代码定期执行。
您应该改用Stopwatch 来测量时间。这就是它的目的。只需在您要测量的操作之前调用Start(),然后在完成后立即调用Stop()。然后,您可以通过Ticks、Milliseconds 或TimeSpan 访问经过的时间。
例如,假设您调用了某种 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();
}
输出