2

我的 WPF 应用程序涉及多个计时器。一切都与 DispatcherTimers 一起工作,但延迟很大并且经常发生冻结(例如 3 秒冻结,然后立即添加剩余的 3 秒)。

我的问题是我不确定我必须如何重新设计我的应用程序才能解决这个问题。以前从未使用过线程,它也是我的第一个真正的 WPF 应用程序。

我收到以下错误: 调用线程必须是 STA,因为许多 UI 组件都需要这个。

我通过使用命名空间 System.Timers 中的 Timer 替换我的 Dispatcher 计时器得到了这个错误

带有调度程序计时器的旧代码:

timerW = new DispatcherTimer();
        timerW.Tick += new EventHandler(timerW_Tick);
        timerW.Interval = new TimeSpan(0, 0, 5000);
        timerW.Start();

带有计时器的新代码:

            timerW = new Timer();
            timerW.Elapsed += new ElapsedEventHandler(timerW_Tick);
            timerW.Interval = 5000; 
            timerW.Start();            

每 5 秒执行一次查询以检索日期值。当满足某些条件时,按钮会动态创建。例如,如果日期在 3 分钟内保持不变,则会创建一个按钮。

动态创建的按钮包含:

  • 数据库中的日期
  • 创建按钮时开始运行的计时器。此计时器仅在创建新按钮时停止,这会记录停机时间。
  • 停机的一个原因

这些按钮保存在ObservableCollection中并使用依赖属性,以便在发生变化时得到通知。它是一个自定义按钮,带有几个文本块来显示信息。

按钮部分是我的程序中所有交互的地方,界面的其余部分只显示来自数据库的信息。这些按钮被放置在一个定制的滑块中,例如带有左右导航按钮的控件。

所以简而言之,我的程序有 3 个不同的调度程序计时器。

  • 一个显示当前时间(hh:mm:ss 格式)
  • 一个执行 sql 查询并每 5 秒检索一次日期值
  • 一种在动态自定义样式的 WPF 按钮内每秒更新停机时间计时器。我用秒表记录中间的停机时间。

所以看来我需要使用踏板和/或后台工作人员?

不知道我实际上是如何开始的,因为我已经有一段时间不太了解了。一些示例代码将是最受欢迎的。

语言:

我使用计时器的原因如下:

  • 显示当前时间
  • 记录停机时间(实时,所以我实际上看到它按秒计算)
  • 每 5 秒执行一次的 SQL 查询。

编辑:

public void InitializeDispatcherTimerW()
    {
        TimerCallback callback = MyTimerCallBack;
        timerWegingen = new Timer(callback, null, 0, 5000);

        timerWegingen.Change(0, 5000);
    }

    private void MyTimerCallBack(object state)
    {
        DisplayWegingInfo();
        CaculateTimeBetweenWegingen();
    }

最好的问候,杰克兹。

4

2 回答 2

1

System.Timers.Timer似乎需要一个 STA 线程。STA 线程是 Windows 窗体的要求,但 WPF 显然不需要它。

System.Threading.Timer是否满足您的需求?

这是一个例子:

// firstTickInterval and interval are TimeSpans
TimerCallback callback = MyTimerCallback;
Timer timer = new Timer(callback, null, firstTickInterval, interval);
// timer is now running
// To stop the timer, do timer.Change(-1, -1);

回调函数如下所示:

void MyTimerCallback(object state)
{
    // This is not guaranteed to execute on the UI thread.
    // In this example, state will be null, since we passed null in the Timer constructor.
}
于 2012-04-16T14:02:15.587 回答
0

当计时器回调代码与 UI 元素交互时,您需要使用:

UIElement.Dispatcher.BeginInvoke(...);

更多信息:http: //msdn.microsoft.com/en-us/magazine/cc163328.aspx

于 2012-04-16T14:29:58.450 回答