1

i am using System.timer.timer class for polling some hardware device through com port(serial Communication) after every 20 seconds, i am initiating the timer.start() from my UI Class and timer_elapse() event is also in UI class.

my question is timer_elapse run on other thread than ui thread or in the same thread? my concern is not regarding how i can update some stuff from timer_elapse to UI, but its something related to performance. (.net 3.5 Framework)

If its part of ui thread than what should i do to take it on other thread so that because of timer_elapse event ui should not get freeze.

I am newbie to C# so any feedback will be greatly appreciable .

Real Master
  • 347
  • 3
  • 14
  • possible duplicate of [Do C# Timers elapse on a separate thread?](http://stackoverflow.com/questions/1435876/do-c-sharp-timers-elapse-on-a-separate-thread) – Brian Gideon Sep 18 '13 at 16:57

2 Answers2

2

When you start a Timer object via Start() function, it creates a new thread and waits until the elapsed time, then when the time is elapsed then The subscribed function or lambda or delegate is called from the timer created thread. So, in case of your example the timer_elapse runs on a completely different thread. See the example below from a sample WPF MainClass:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        System.Threading.Thread.CurrentThread.Name = "UI THREAD";
        System.Timers.Timer t = new System.Timers.Timer(500);
        System.Threading.Thread td = new System.Threading.Thread(
            (obj) => 
            { 
                Console.WriteLine("Thread");
                t.Elapsed += new System.Timers.ElapsedEventHandler(t_Elapsed);
                t.Start();
                while (true)
                {
                    System.Threading.Thread.Sleep(1000);
                    Console.WriteLine("From Lambda: Current Thread Name: " + System.Threading.Thread.CurrentThread.Name);
                }
            }
            );
        td.Name = "K's Thread";
        td.Start(null);
    }

    void t_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        Console.WriteLine("t_Elapsed: Current Thread Name: " + System.Threading.Thread.CurrentThread.Name);
    }
}

And Notice The output in the debug console that the Timer function's Thread name is not the same name as the UI Thread.

So you won't have to worry about hanging up your UI thread. But if you try to change some controls, it may throw exception (not always). So to perform any UI related work, it is best practice to do it in the UI thread. You can do it Getting the Dispatcher to the UI thread from Application.Current.Dispatcher

Example is below:

public partial class MainWindow : Window
    {
        delegate void TestDelegate();
        public MainWindow()
        {
            InitializeComponent();

            System.Threading.Thread.CurrentThread.Name = "UI THREAD";
            System.Timers.Timer t = new System.Timers.Timer(500);
            System.Threading.Thread td = new System.Threading.Thread(
                (obj) => 
                { 
                    Console.WriteLine("Thread");
                    t.Elapsed += new System.Timers.ElapsedEventHandler(t_Elapsed);
                    t.Start();
                    while (true)
                    {
                        System.Threading.Thread.Sleep(1000);
                        Console.WriteLine("From Lambda: Current Thread Name: " + System.Threading.Thread.CurrentThread.Name);
                    }
                }
                );
            td.Name = "K's Thread";
            td.Start(null);
        }

        void DoInUIThread()
        {
            Console.WriteLine("DoInUIThread: Current Thread Name: " + System.Threading.Thread.CurrentThread.Name);
        }

        void t_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            Console.WriteLine("t_Elapsed: Current Thread Name: " + System.Threading.Thread.CurrentThread.Name);
            TestDelegate td = new TestDelegate(DoInUIThread);
            Application.Current.Dispatcher.BeginInvoke(td );
        }
    }
K'Prime
  • 98
  • 4
1

timer_elapse runs on a different thread than the UI. If you want to reference UI components in timer_elapse you need to use the Dispatcher, e.g.

    Dispatcher.BeginInvoke(new Action(() =>
    {
        // UI code
    }));
DaveDev
  • 41,155
  • 72
  • 223
  • 385
  • it will be great if you can provide me some links or something, which will surely help to understand the concept thoroughly. – Real Master Sep 18 '13 at 16:38
  • 1
    @HarshalSam Why? It's a simple yes/no question. The Timer's code could have been written to marshall to a UI context or not; that particular timer does not. That's all there is to it. If you want to use a timer that will marshall to the UI thread, there are plenty out there that will, depending on your particular UI framework. – Servy Sep 18 '13 at 16:40
  • http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.begininvoke.aspx – DaveDev Sep 18 '13 at 16:40
  • 2
    @DaveDev You don't know if this is a WPF application, so `Dispatcher` may not be the appropriate tool. Also, based on the question, he doesn't *want* the timer to do the work in the UI thread, so he wouldn't need it regardless. – Servy Sep 18 '13 at 16:41
  • @SERVY thanks for understanding my question, it might be my mistake that i have not described the question correctly.. – Real Master Sep 18 '13 at 16:46
  • 2
    @DaveDev: An event handler on `Elapsed` from `System.Timers.Timer` [can execute on the UI thread](http://stackoverflow.com/a/1436331/158779). Depending on how the OP created the timer it is very possible that it actually is executing on the UI thread. – Brian Gideon Sep 18 '13 at 17:02