首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >system.timer.timer是否不是ui线程?

system.timer.timer是否不是ui线程?
EN

Stack Overflow用户
提问于 2013-09-18 16:35:38
回答 2查看 6K关注 0票数 1

每隔20秒,我就使用System.timer.timer类通过com端口(串行通信)轮询一些硬件设备,我从UI类启动timer.start(),timer_elapse()事件也在UI类中。

我的问题是timer_elapse运行在ui线程以外的其他线程上,还是运行在同一个线程中?我关心的不是如何将一些内容从timer_elapse更新到UI,而是一些与性能有关的内容。(.net 3.5框架)

如果它的ui线程部分比我应该做的其他线程要做的多,那么由于timer_elapse事件,ui不应该被冻结。

我是C#的新手,所以任何反馈都会非常感谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-09-18 17:11:40

当您通过Start()函数启动一个Timer对象时,它会创建一个新的线程,并等待到经过的时间,然后在经过这个时间之后,从定时器创建的线程中调用订阅函数或lambda或委托。因此,在您的示例中,timer_elapse运行在一个完全不同的线程上。参见下面示例WPF MainClass中的示例:

代码语言:javascript
复制
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);
    }
}

注意调试控制台中的输出,计时器函数的线程名与UI线程名称不同。

这样您就不用担心挂掉UI线程了。但是,如果您试图更改某些控件,则可能会引发异常(并非总是如此)。因此,要执行任何与UI相关的工作,最好在UI线程中这样做。您可以从Application.Current.Dispatcher将Dispatcher发送到UI线程

例子如下:

代码语言:javascript
复制
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 );
        }
    }
票数 2
EN

Stack Overflow用户

发布于 2013-09-18 16:37:22

timer_elapse运行在与UI不同的线程上。如果要在timer_elapse中引用UI组件,则需要使用Dispatcher。

代码语言:javascript
复制
    Dispatcher.BeginInvoke(new Action(() =>
    {
        // UI code
    }));
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18877671

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档