C# 秒表的替代品?

C# 秒表的替代品?,c#,wpf,stopwatch,C#,Wpf,Stopwatch,我正在使用WPF制作一个非常简单的秒表,但使用的是系统。与我的系统时钟相比,Diagnostics秒表速度非常慢,根本不可靠。我的应用程序每1秒的实际时钟为3秒 我做了一些关于秒表慢的搜索,发现了很多结果,但没有解决办法,所以我决定拿出我自己的计数器 下面是我想到的一个例子: System.Windows.Threading.DispatcherTimer _update; DateTime _started; bool isRunning = false; 更新线程: _update = n

我正在使用WPF制作一个非常简单的秒表,但使用的是
系统。与我的系统时钟相比,Diagnostics
秒表速度非常慢,根本不可靠。我的应用程序每1秒的实际时钟为3秒

我做了一些关于秒表慢的搜索,发现了很多结果,但没有解决办法,所以我决定拿出我自己的计数器

下面是我想到的一个例子:

System.Windows.Threading.DispatcherTimer _update;
DateTime _started;
bool isRunning = false;
更新线程:

_update = new System.Windows.Threading.DispatcherTimer(new TimeSpan(0, 0, 0, 0, 1), System.Windows.Threading.DispatcherPriority.Normal, delegate
{
    if (isRunning)
        iTimer.Content = new DateTime((DateTime.Now - _started).Ticks).ToString("HH:mm:ss");
}, this.Dispatcher);
我有两个按钮,B按钮负责启动、停止和恢复,另一个按钮叫bReset

private void bReset_Click(object sender, RoutedEventArgs e)
{
    isRunning = false;
    iTimer.Content = "00:00:00";
    bToggle.Content = "Start";
}

private void bToggle_Click(object sender, RoutedEventArgs e)
{
    if ((string)bToggle.Content == "Start")
    {
        isRunning = true;
        _started = DateTime.Now;
        bToggle.Content = "Stop";
    }
    else if ((string)bToggle.Content == "Resume")
    {
        isRunning = true;
        bToggle.Content = "Stop";
    }
    else
    {
        isRunning = false;
        bToggle.Content = "Resume";
    }
}
它可以很好地启动和重置,但由于我使用的是实际时间,如果我停止并恢复,它将跳转秒数直到实际时间


我该如何解决这个问题,或者是否有一种替代秒表的方法,它在当前时间上的准确度确实很高?

您需要引入一个附加变量
TimeSpan acculatedTime
,在该变量中,每当有人单击“停止”时,您都会保存经过的时间间隔

以及:


使用
System.Timers.Timer

您可以启动和停止此操作,并在timers tick事件中设置计数器

这是一个简单的例子:

public partial class MainWindow : Window
{
    private Timer _timer;
    private int _time;

    public MainWindow()
    {
        InitializeComponent();

        _time = 0;

        _timer = new Timer(1000);
        _timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
    }

    void _timer_Elapsed(object sender, ElapsedEventArgs e)
    {

        Dispatcher.Invoke(new Action(() =>
                                         {
                                             _time++;
                                             tbTime.Text = _time.ToString();
                                         }));

    }

    private void btnStartStop_Click(object sender, RoutedEventArgs e)
    {
        if (_timer.Enabled)
        {
            _timer.Stop();
        }
        else
        {
            _timer.Start();
        }
    }
}
Xaml:


我认为这一行是你的问题:

_update = new System.Windows.Threading.DispatcherTimer(new TimeSpan(0, 0, 0, 0, 1), System.Windows.Threading.DispatcherPriority.Normal
它告诉WPF您希望您的委托每秒执行1000次,并将其安排在第二高优先级。这比
Render
DataBind
的优先级更高,我认为Render和DataBind都需要实际显示您在
iTimer.Content
中输入的更新值


您应该将DispatcherPriority设置为Background,并使用较低的频率(例如20毫秒-人类看东西的速度无论如何都不能超过50 fps)。

您使用秒表的目的是什么?简单地说,它从0开始计数,直到你停止或重置。听起来你只是想用它作为计时器。类似这样的东西,但作为桌面应用程序。无论哪种方式,如果你看上面的代码,这是一个完整的工作,我只需要找出如何做停止/恢复功能,或者是否有更好的方法来控制它。
StopWatch
在一些硬件上有问题(例如核心之间的恒定偏移),但我从来没有听说过乘法错误。你能发布你的秒表代码吗?非常感谢,我已经通过以下方式解决了它:
newdatetime((DateTime.Now.Subtract(acgregatedtime)-(u tempo.Ticks)。ToString(“HH:mm:ss”)我使用线程的事实是,它不会挂起我的应用程序UI。这不会锁定你的UI,但如果你想安全起见,请将计时器放在backgroundworker中,如果你不断移动应用程序窗口,则将滴答事件转发给worker progresschanged eventjrb。我所问的代码更新得很好,但使用stopwatch类时,情况并非如此,因此,在我看来,这条线会成为问题所在。
<Grid>
    <StackPanel>
        <Button Name="btnStartStop" Content="start/stop timer" Click="btnStartStop_Click" />
        <TextBlock Name="tbTime" Text="00:00" />
    </StackPanel>
</Grid>
_update = new System.Windows.Threading.DispatcherTimer(new TimeSpan(0, 0, 0, 0, 1), System.Windows.Threading.DispatcherPriority.Normal