我使用System.timer.timer类在每20秒后通过com端口(串行通信)轮询一些硬件设备,我从我的UI类启动timer.start()并且timer_elapse()事件也在UI类。
我的问题是在ui线程或同一线程的其他线程上运行timer_elapse?我关注的不是如何将一些东西从timer_elapse更新到UI,而是它与性能相关的东西。 (.net 3.5框架)
如果它的部分ui线程比我应该做的那样把它带到其他线程上,这样因为timer_elapse事件ui不应该被冻结。
我是C#的新手,所以任何反馈都会非常明显。
答案 0 :(得分:2)
当你通过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);
}
}
并注意调试控制台中Timer函数的Thread名称与UI Thread名称不同的输出。
所以你不必担心挂起你的UI线程。但是如果你试图改变一些控件,它可能会抛出异常(并不总是)。因此,要执行任何与UI相关的工作,最好在UI线程中执行此操作。您可以从Application.Current.Dispatcher
示例如下:
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 );
}
}
答案 1 :(得分:0)
timer_elapse
在与UI不同的线程上运行。如果要在timer_elapse
中引用UI组件,则需要使用Dispatcher,例如
Dispatcher.BeginInvoke(new Action(() =>
{
// UI code
}));