Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实现倒计时计时器/时钟的更有效方法?_C#_.net_Performance_User Interface - Fatal编程技术网

C# 实现倒计时计时器/时钟的更有效方法?

C# 实现倒计时计时器/时钟的更有效方法?,c#,.net,performance,user-interface,C#,.net,Performance,User Interface,我正在为老虎机赛车写一个小圈数计数器,作为一个小家庭项目。我想实现一个倒计时计时器,我已经做了以下测试: private Thread countdownThread; private delegate void UpdateTimer(string update); UpdateTimer ut; public LapCounterForm() { InitializeComponent(); //... ut += updateTimer; countdownThre

我正在为老虎机赛车写一个小圈数计数器,作为一个小家庭项目。我想实现一个倒计时计时器,我已经做了以下测试:

private Thread countdownThread;
private delegate void UpdateTimer(string update);
UpdateTimer ut;
public LapCounterForm()
{
   InitializeComponent();
   //...
   ut += updateTimer;
   countdownThread = new Thread(new ThreadStart(startCountdown));
}

private void startCountdown()
{
    Process.GetCurrentProcess().ProcessorAffinity = new IntPtr(1);
    Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High;
    Thread.CurrentThread.Priority = ThreadPriority.AboveNormal;
    System.Diagnostics.Stopwatch stopwatch = new Stopwatch();
    long time = 0;
    stopwatch.Start();

    while (stopwatch.ElapsedMilliseconds <= 5000)
    {
        time = 5000 - stopwatch.ElapsedMilliseconds;
        TimeSpan ts = TimeSpan.FromMilliseconds(time);
        ut(ts.Minutes.ToString().PadLeft(2, '0') + ":" + ts.Seconds.ToString().PadLeft(2, '0') + ":" + ts.Milliseconds.ToString().PadLeft(3, '0'));
    }

}

private void updateTimer(string text)
{
    if (this.InvokeRequired)
    {
        this.Invoke(new Action<String>(ut), new object[] { text });
    }
    else
    {
        lblCountdownClock.Text = text;
    }
}
私有线程倒计时线程;
私有委托void UpdateTimer(字符串更新);
更新程序ut;
公共模板()
{
初始化组件();
//...
ut+=updateTimer;
countdownThread=新线程(新线程开始(startCountdown));
}
私有void startCountdown()
{
Process.GetCurrentProcess().ProcessorAffinity=new IntPtr(1);
Process.GetCurrentProcess().PriorityClass=ProcessPriorityClass.High;
Thread.CurrentThread.Priority=ThreadPriority.Overnormal;
System.Diagnostics.Stopwatch秒表=新秒表();
长时间=0;
秒表。开始();

虽然(stopwatch.elapsedmillyseconds不要,只是不要沿着这条路走。你完全用错误的方式思考这个问题。你基本上是在强迫线程冻结而没有任何好处

基本上,任何游戏都是这样工作的:你有一个更新循环,每当它触发时,你都会做一些必要的事情。例如,如果你想知道有多少时间,你可以问一些“计时器”从事情发生到现在已经过去了多少时间

这里有一个更好的处理方法:

class MyStopwatch {
    private DateTime _startTime;
    private DateTime _stopTime;

    public void start() {
        _running = true;
        _startTime = DateTime.Now;
    }

    public void stop() {
        _stopTime = DateTime.Now;
        _running = false;
    }

    public double getTimePassed() {
        if(_running) {
            return (DateTime.Now - _startTime).TotalMilliseconds;
        } else {
            return (_stopTime - _startTime).TotalMilliseconds;
        }
    }
}

不要,只是不要走这条路。你完全是用错误的方式思考这个问题。你基本上是在强迫你的线程冻结,没有任何好处

基本上,任何游戏都是这样工作的:你有一个更新循环,每当它触发时,你都会做一些必要的事情。例如,如果你想知道有多少时间,你可以问一些“计时器”从事情发生到现在已经过去了多少时间

这里有一个更好的处理方法:

class MyStopwatch {
    private DateTime _startTime;
    private DateTime _stopTime;

    public void start() {
        _running = true;
        _startTime = DateTime.Now;
    }

    public void stop() {
        _stopTime = DateTime.Now;
        _running = false;
    }

    public double getTimePassed() {
        if(_running) {
            return (DateTime.Now - _startTime).TotalMilliseconds;
        } else {
            return (_stopTime - _startTime).TotalMilliseconds;
        }
    }
}

在事实发生后一点,但这显示了一种实现您需要的方式:

public class LapTimer : IDisposable
{
    private readonly System.Diagnostics.Stopwatch _stopWatch = new System.Diagnostics.Stopwatch();
    private readonly ConcurrentDictionary<string, List<TimeSpan>> _carLapTimes = new ConcurrentDictionary<string, List<TimeSpan>>();
    private readonly Action<TimeSpan> _countdownReportingDelegate;
    private readonly TimeSpan _countdownReportingInterval;
    private System.Threading.Timer _countDownTimer;
    private TimeSpan _countdownTo = TimeSpan.FromSeconds(5);

    public LapTimer(TimeSpan countdownReportingInterval, Action<TimeSpan> countdownReporter)
    {
        _countdownReportingInterval = countdownReportingInterval;
        _countdownReportingDelegate = countdownReporter;
    }

    public void StartRace(TimeSpan countdownTo)
    {
        _carLapTimes.Clear();
        _stopWatch.Restart();
        _countdownTo = countdownTo;
        _countDownTimer = new System.Threading.Timer(this.CountdownTimerCallback, null, _countdownReportingInterval, _countdownReportingInterval);
    }

    public void RaceComplete()
    {
        _stopWatch.Stop();
        _countDownTimer.Dispose();
        _countDownTimer = null;
    }

    public void CarCompletedLap(string carId)
    {
        var elapsed = _stopWatch.Elapsed;
        _carLapTimes.AddOrUpdate(carId, new List<TimeSpan>(new[] { elapsed }), (k, list) => { list.Add(elapsed); return list; });
    }

    public IEnumerable<TimeSpan> GetLapTimesForCar(string carId)
    {
        List<TimeSpan> lapTimes = null;
        if (_carLapTimes.TryGetValue(carId, out lapTimes))
        {
            yield return lapTimes[0];
            for (int i = 1; i < lapTimes.Count; i++)
                yield return lapTimes[i] - lapTimes[i - 1];
        }
        yield break;
    }

    private void CountdownTimerCallback(object state)
    {
        if (_countdownReportingDelegate != null)
            _countdownReportingDelegate(_countdownTo - _stopWatch.Elapsed);
    }

    public void Dispose()
    {
        if (_countDownTimer != null)
        {
            _countDownTimer.Dispose();
            _countDownTimer = null;
        }
    }
}

class Program
{
    public static void Main(params string[] args)
    {
        using (var lapTimer = new LapTimer(TimeSpan.FromMilliseconds(100), remaining => Console.WriteLine(remaining)))
        {
            lapTimer.StartRace(TimeSpan.FromSeconds(5));
            System.Threading.Thread.Sleep(2000);
            lapTimer.RaceComplete();
        }
        Console.ReadLine();
    }
}
公共类LapTimer:IDisposable
{
private readonly System.Diagnostics.Stopwatch _Stopwatch=new System.Diagnostics.Stopwatch();
私有只读ConcurrentDictionary _carLapTimes=新ConcurrentDictionary();
私有只读操作countdownReportingDelegate;
私有只读时间跨度_倒计时报告间隔;
专用系统.Threading.Timer\u倒计时;
专用时间间隔_countdownTo=时间间隔从秒开始(5);
公共LapTimer(TimeSpan countdownReportingInterval、Action countdownReporter)
{
_countdownReportingInterval=countdownReportingInterval;
_countdownReportingDelegate=countdownReporter;
}
公共空星跟踪(时间跨度倒计时)
{
_carLapTimes.Clear();
_stopWatch.Restart();
_倒计时到=倒计时到;
_countDownTimer=new System.Threading.Timer(this.countDownTimer回调,null,_countdownReportingInterval,_countdownReportingInterval);
}
公共图书馆
{
_秒表;
_countDownTimer.Dispose();
_倒计时=空;
}
公共空间CarCompletedLap(字符串carId)
{
var经过时间=_stopWatch.appeased;
_carLapTimes.AddOrUpdate(carId,新列表(new[]{appeased}),(k,List)=>{List.Add(appeased);return List;});
}
公共IEnumerable GetLapTimesForCar(字符串carId)
{
列表时间=空;
如果(_carLapTimes.TryGetValue(carId,超出圈数))
{
收益返回圈数[0];
对于(int i=1;iConsole.WriteLine(剩余)))
{
lapTimer.StartRace(TimeSpan.FromSeconds(5));
系统线程线程睡眠(2000);
lapTimer.raceplete();
}
Console.ReadLine();
}
}

稍晚一点,但这显示了您可能实现所需的一种方式:

public class LapTimer : IDisposable
{
    private readonly System.Diagnostics.Stopwatch _stopWatch = new System.Diagnostics.Stopwatch();
    private readonly ConcurrentDictionary<string, List<TimeSpan>> _carLapTimes = new ConcurrentDictionary<string, List<TimeSpan>>();
    private readonly Action<TimeSpan> _countdownReportingDelegate;
    private readonly TimeSpan _countdownReportingInterval;
    private System.Threading.Timer _countDownTimer;
    private TimeSpan _countdownTo = TimeSpan.FromSeconds(5);

    public LapTimer(TimeSpan countdownReportingInterval, Action<TimeSpan> countdownReporter)
    {
        _countdownReportingInterval = countdownReportingInterval;
        _countdownReportingDelegate = countdownReporter;
    }

    public void StartRace(TimeSpan countdownTo)
    {
        _carLapTimes.Clear();
        _stopWatch.Restart();
        _countdownTo = countdownTo;
        _countDownTimer = new System.Threading.Timer(this.CountdownTimerCallback, null, _countdownReportingInterval, _countdownReportingInterval);
    }

    public void RaceComplete()
    {
        _stopWatch.Stop();
        _countDownTimer.Dispose();
        _countDownTimer = null;
    }

    public void CarCompletedLap(string carId)
    {
        var elapsed = _stopWatch.Elapsed;
        _carLapTimes.AddOrUpdate(carId, new List<TimeSpan>(new[] { elapsed }), (k, list) => { list.Add(elapsed); return list; });
    }

    public IEnumerable<TimeSpan> GetLapTimesForCar(string carId)
    {
        List<TimeSpan> lapTimes = null;
        if (_carLapTimes.TryGetValue(carId, out lapTimes))
        {
            yield return lapTimes[0];
            for (int i = 1; i < lapTimes.Count; i++)
                yield return lapTimes[i] - lapTimes[i - 1];
        }
        yield break;
    }

    private void CountdownTimerCallback(object state)
    {
        if (_countdownReportingDelegate != null)
            _countdownReportingDelegate(_countdownTo - _stopWatch.Elapsed);
    }

    public void Dispose()
    {
        if (_countDownTimer != null)
        {
            _countDownTimer.Dispose();
            _countDownTimer = null;
        }
    }
}

class Program
{
    public static void Main(params string[] args)
    {
        using (var lapTimer = new LapTimer(TimeSpan.FromMilliseconds(100), remaining => Console.WriteLine(remaining)))
        {
            lapTimer.StartRace(TimeSpan.FromSeconds(5));
            System.Threading.Thread.Sleep(2000);
            lapTimer.RaceComplete();
        }
        Console.ReadLine();
    }
}
公共类LapTimer:IDisposable
{
private readonly System.Diagnostics.Stopwatch _Stopwatch=new System.Diagnostics.Stopwatch();
私有只读ConcurrentDictionary _carLapTimes=新ConcurrentDictionary();
私有只读操作countdownReportingDelegate;
私有只读时间跨度_倒计时报告间隔;
专用系统.Threading.Timer\u倒计时;
专用时间间隔_countdownTo=时间间隔从秒开始(5);
公共LapTimer(TimeSpan countdownReportingInterval、Action countdownReporter)
{
_countdownReportingInterval=countdownReportingInterval;
_countdownReportingDelegate=countdownReporter;
}
公共空星跟踪(时间跨度倒计时)
{
_carLapTimes.Clear();
_stopWatch.Restart();
_倒计时到=倒计时到;
_countDownTimer=new System.Threading.Timer(this.countDownTimer回调,null,_countdownReportingInterval,_countdownReportingInterval);
}
公共图书馆
{
_秒表;
_countDownTimer.Dispose();
_倒计时=空;
}
公共空间CarCompletedLap(字符串carId)
{
var经过时间=_stopWatch.appeased;
_carLapTimes.AddOrUpdate(carId,新列表(new[]{appeased}),(k,List)=>{List.Add(appeased);return List;});
}
公共IEnumerable GetLapTimesForCar(字符串carId)
{
列表时间=空;
如果(_carLapTimes.TryGetValue(carId,超出圈数))
{
收益返回圈数[0];
对于(int i=1;i