每隔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#的新手,所以任何反馈都会非常感谢。
发布于 2013-09-18 17:11:40
当您通过Start()函数启动一个Timer对象时,它会创建一个新的线程,并等待到经过的时间,然后在经过这个时间之后,从定时器创建的线程中调用订阅函数或lambda或委托。因此,在您的示例中,timer_elapse运行在一个完全不同的线程上。参见下面示例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);
}
}注意调试控制台中的输出,计时器函数的线程名与UI线程名称不同。
这样您就不用担心挂掉UI线程了。但是,如果您试图更改某些控件,则可能会引发异常(并非总是如此)。因此,要执行任何与UI相关的工作,最好在UI线程中这样做。您可以从Application.Current.Dispatcher将Dispatcher发送到UI线程
例子如下:
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 );
}
}发布于 2013-09-18 16:37:22
timer_elapse运行在与UI不同的线程上。如果要在timer_elapse中引用UI组件,则需要使用Dispatcher。
Dispatcher.BeginInvoke(new Action(() =>
{
// UI code
}));https://stackoverflow.com/questions/18877671
复制相似问题