Search code examples
c#program-entry-pointdispatchertimer

DispatcherTimer in a new thread


I'm developing a c# application. I need 2 threads; the main one, and another that is continuously looking for information through my database. I want to use Dispatcher Timer as:

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

If i do this into my main thread, everything works perfectly, but if I do into a new thread. It doesn't work.

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();
}

What's the problem?


Solution

  • As you stated in the comments, you declare dispatcherBd as a local variable inside InitDispatcher():

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

    So dispatcherBd is only in scope inside InitDispatcher and will be availabe for garbage collection as soon as the method is left.
    When it gets garbage collected and finalized, the timer event will no longer be raised.

    So try changing dispatcherBd to a field instead:

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

    But note that DispatcherTimer invokes its handler on the UI thread. So if CallPoll takes a lot of time, your UI will be blocked.
    So you might want to start another thread from the timer's handler:

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

    or use a System.Threading.Timer instead of a DispatcherTimer. That one runs the Tick event on a thread pool thread.

    In both cases you need to get back to the UI thread when you want to display the results on your UI.