簡體   English   中英

在 c# 中運行計時器時運行其他代碼

[英]Run other code while timer is running in c#

我正在進行 C# 控制台數學測試,用戶在其中回答數學問題

我正在嘗試在測試中添加一個計時器,但我不能讓我的計時器與我的其他代碼同時運行

這是我的代碼示例:

class Program
{
    public static OtherCode()
    {
        \\*other code for test
    }
    public class Timer
    {
        public static int Timers(int timeLeft)
        {
            do
            {
                Console.Write("\rtimeLeft: {0} ", timeLeft);
                timeLeft--;
                Thread.Sleep(1000);
            } while (timeLeft > 0);
            Console.Write(Environment.NewLine);
            return timeLeft;
        }
    }

    public static void Main(string[] args)
    {
        int numberOfSeconds = 30;
        Timer.Timers(numberOfSeconds);

        \\other code
        OtherCode();
    }
}

這是我的完整代碼: https://github.com/CrazyDanyal1414/mathstester

我希望我的計時器在控制台頂部運行,並且像這樣在下面詢問數學問題,除了問題應該在換行符上: 在此處輸入圖像描述

任何幫助表示贊賞!

更新

當我將 Console.SetCursorPosition() 添加到我的代碼中時,如下所示:

do
    {
        Console.SetCursorPosition(0, 9);        
        Console.Write("\rtimeLeft: {0} ", timeLeft);
        timeLeft--;
        Thread.Sleep(1000);
    } while (timeLeft > 0);

我的代碼不會移動計時器,但是當我鍵入我的一個數學問題的答案時,它會讓我在與計時器相同的行上鍵入它,如下所示: 在此處輸入圖像描述

您可以在第二個線程內啟動 Timers 方法。

為此,您需要使用System.Threading命名空間。 看一下: 啟動參數化線程

為了讓狀態消息留在控制台底部,您需要一種操作屏幕緩沖區的方法,以便不斷覆蓋您的狀態消息。

Console.SetCursorPos可用於此,並且在更高級的場景中很有用,但我認為您只需使用 \r 將 cursor 重置為行首即可。

概念證明:

using System;

namespace consoletimer
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            int numberOfSeconds = 300;
            var thread = new System.Threading.Thread(()=> PrintStatusMessage(numberOfSeconds));
            thread.Start();
            int n = 5;
            while(n-- > 0){
                WriteToScreen("Example text", false);
                ReadInput();
                System.Threading.Thread.Sleep(2000);
            }
        }

        static void PrintStatusMessage(int numberOfSeconds){
            var whenToStop = DateTime.Now.AddSeconds(numberOfSeconds);
            while(DateTime.Now < whenToStop){
                var timeLeft = (whenToStop-DateTime.Now).ToString(@"hh\:mm\:ss");
                WriteToScreen($"Time Remaining: {timeLeft}", true);
                System.Threading.Thread.Sleep(500);
            }
        }

        static string ReadInput(){
            string input = Console.ReadLine();
            Console.Write(new string(' ',100));
            Console.CursorLeft = 0;
            return input;
        }

        static object lockObject = new object();

        static void WriteToScreen(string message, bool resetCursor){
            lock(lockObject){
                if(resetCursor){
                    int leftPos = Console.CursorLeft;
                    Console.WriteLine();
                    Console.Write(message.PadRight( 50, ' '));
                    Console.CursorTop--;
                    Console.CursorLeft = leftPos;
                }
                else{
                    Console.WriteLine(message);
                    Console.Write(new string(' ',100));
                    Console.CursorLeft = 0;
                }   
            }
        }
    }    
}

編輯

每當我們寫入控制台時,我們都需要清除下一行,以便刪除之前存在的狀態消息。

您可以通過這種方式簡單地使用線程

using System.Threading;

namespace ConsoleApp1
{
    class Program
    {
        public static void OtherCode()
        {
            Console.ReadKey();
            //other code for test
        }

        public static void Main(string[] args)
        {

            Thread thread = new Thread(new ThreadStart(Job));
            thread.Start();

            //other code
            OtherCode();
        }

        public static void Job()
        {
            int numberOfSeconds = 30;
            Timer.Timers(numberOfSeconds);
        }
    }

    class Timer
    {
        public static int Timers(int timeLeft)
        {
            do
            {
                Console.Write("\rtimeLeft: {0} ", timeLeft);
                timeLeft--;
                Thread.Sleep(1000);
            } while (timeLeft > 0);
            Console.Write(Environment.NewLine);
            return timeLeft;
        }
    }
}

或者

    public static void Main(string[] args)
    {

        Thread thread = new Thread(new ThreadStart(() => {
            int numberOfSeconds = 30;
            Timer.Timers(numberOfSeconds);
        }));
        thread.Start();

        //other code
        OtherCode();
    }

暫無
暫無

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

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