新线程中的 DispatcherTimer

DispatcherTimer in a new thread

我正在开发 C# 应用程序。我需要 2 个线程;主要的一个,另一个是不断通过我的数据库查找信息。 我想将 Dispatcher Timer 用作:

dispatcherBd.Tick += (s,e) => CallPoll (s,e);
dispatcherBd.Interval = new TimeSpan(0,0,0,100);
dispatcherBd.Start();

如果我在我的主线程中执行此操作,则一切正常,但如果我在新线程中执行此操作。没用。

public Main(){
    threadDB = new Thread(InitDispatcher);
    threadDB.Start();
}

private void InitDispatcher(){
    DispatcherTimer dispatcherBd.Tick += (s,e) => CallPoll (s,e);
    dispatcherBd.Interval = new TimeSpan(0,0,0,100);
    dispatcherBd.Start();
}

有什么问题?

如您在评论中所述,您将 dispatcherBd 声明为 local 变量 inside InitDispatcher():

private void InitDispatcher()
{
    DispatcherTimer dispatcherBd = new DispatcherTimer();
    // ...

因此 dispatcherBd 仅在 InitDispatcher 内的范围内,并且一旦离开该方法将可用于垃圾回收。
当它被垃圾收集并完成时,将不再引发计时器事件。

所以尝试将 dispatcherBd 改为 字段

private DispatcherTimer dispatcherBd;

private void InitDispatcher()
{
    dispatcherBd = new DispatcherTimer();
    // ...

但请注意 DispatcherTimer 在 UI 线程上调用其处理程序。因此,如果 CallPoll 花费大量时间,您的 UI 将被阻止。
所以你可能想从计时器的处理程序启动另一个线程:

dispatcherBd.Tick += (s, e) => { Task.Run(() => CallPoll(s, e)) };

或使用 System.Threading.Timer 而不是 DispatcherTimer。那个在线程池线程上运行 Tick 事件。

在这两种情况下,当您想要在 UI 上显示结果时,您需要返回到 UI 线程。

除非绝对必要,否则请忘记手动穿线。使用 Task.Run 作为在另一个线程上安排您的(可能的,连续的)工作的一种方式。如果您需要从新创建的(非UI)线程更新您的 UI,请不要忘记 Dispatcher.Invoke 代理。

如果事情变得太复杂,请考虑 Reactive Extensions。有开箱即用的定时器,还有很多很多。