调用线程必须是STA

我试图模拟一个抛射物并试图在定时事件中只创建一次标签,因为它在参数中有一个对象,我需要在定时事件中。 但是当我运行它时,我得到了这个线程错误。 请帮忙!

我的代码是:

void onTimedEvent(Object source, ElapsedEventArgs e) { particle newProjectile; newProjectile = new particle(); bool LabelExist = false; if (LabelExist == false) { CreateLabels(newProjectile); } } aTimer = new System.Timers.Timer(200); aTimer.Elapsed += onTimedEvent; aTimer.Enabled = true; void CreateLabels(particle newProjectile) { DockPanel panelcontrol_displacement, panelcontrol_CurrentVel, panelcontrol_VerticalVel, panelcontrol_HorizontalVel, panelcontrol_Time; Label lbl_TimeUnits, lbl_TimeOutput, lbl_Time, lbl_DisplacementOutput, lbl_DisplacementUnits, lbl_Displacement, lbl_CurrentVel, lbl_CurrentVelOutput, lbl_HorizontalVelocityOutputs, lbl_HorizontalVelocityUnits, lbl_VerticalVelocity, lbl_HorizontalVelocity, lbl_CurrentVelUnits, lbl_VerticalVelocityOutput, lbl_VerticalVelocityUnits; lbl_Time = new Label(); lbl_Time.Content = "Time"; lbl_Time.Height = 30; lbl_Time.Width = 110; lbl_TimeOutput = new Label(); lbl_TimeOutput.Content = "20"; lbl_TimeOutput.Height = 30; lbl_TimeOutput.Width = 100; lbl_TimeOutput.HorizontalContentAlignment = HorizontalAlignment.Right; lbl_TimeUnits = new Label(); lbl_TimeUnits.Content = "s"; lbl_CurrentVel = new Label(); lbl_CurrentVel.Content = "Current Velocity"; lbl_CurrentVel.Height = 30; lbl_CurrentVel.Width = 110; lbl_CurrentVelOutput = new Label(); lbl_CurrentVelOutput.Content = "20"; lbl_CurrentVelOutput.Height = 30; lbl_CurrentVelOutput.Width = 100; lbl_CurrentVelOutput.HorizontalContentAlignment = HorizontalAlignment.Right; lbl_CurrentVelUnits = new Label(); lbl_CurrentVelUnits.Content = "m/s"; lbl_VerticalVelocity = new Label(); lbl_VerticalVelocity.Content = "Verticle Velocity"; lbl_VerticalVelocity.Height = 30; lbl_VerticalVelocity.Width = 110; lbl_VerticalVelocityOutput = new Label(); lbl_VerticalVelocityOutput.Content = "20"; lbl_VerticalVelocityOutput.Height = 30; lbl_VerticalVelocityOutput.Width = 100; lbl_VerticalVelocityOutput.HorizontalContentAlignment = HorizontalAlignment.Right; lbl_VerticalVelocityUnits = new Label(); lbl_VerticalVelocityUnits.Content = "m/s"; lbl_HorizontalVelocity = new Label(); lbl_HorizontalVelocity.Content = "Horizontal Velocity"; lbl_HorizontalVelocity.Height = 30; lbl_HorizontalVelocity.Width = 110; lbl_HorizontalVelocityOutputs = new Label(); lbl_HorizontalVelocityOutputs.Content = "20"; lbl_HorizontalVelocityOutputs.Height = 30; lbl_HorizontalVelocityOutputs.Width = 100; lbl_HorizontalVelocityOutputs.HorizontalContentAlignment = HorizontalAlignment.Right; lbl_HorizontalVelocityUnits = new Label(); lbl_HorizontalVelocityUnits.Content = "m/s"; lbl_Displacement = new Label(); lbl_Displacement.Content = "Displacement"; lbl_Displacement.Height = 30; lbl_Displacement.Width = 110; lbl_DisplacementOutput = new Label(); lbl_DisplacementOutput.Content = "20"; lbl_DisplacementOutput.Height = 30; lbl_DisplacementOutput.Width = 100; lbl_DisplacementOutput.HorizontalContentAlignment = HorizontalAlignment.Right; lbl_DisplacementUnits = new Label(); lbl_DisplacementUnits.Content = "m/s"; panelcontrol_HorizontalVel = new DockPanel(); panelcontrol_CurrentVel = new DockPanel(); panelcontrol_VerticalVel = new DockPanel(); panelcontrol_displacement = new DockPanel(); panelcontrol_Time = new DockPanel(); panelcontrol_CurrentVel.Children.Add(lbl_CurrentVel); panelcontrol_CurrentVel.Children.Add(lbl_CurrentVelOutput); panelcontrol_CurrentVel.Children.Add(lbl_CurrentVelUnits); panelcontrol_VerticalVel.Children.Add(lbl_VerticalVelocity); panelcontrol_VerticalVel.Children.Add(lbl_VerticalVelocityOutput); panelcontrol_VerticalVel.Children.Add(lbl_VerticalVelocityUnits); panelcontrol_HorizontalVel.Children.Add(lbl_HorizontalVelocity); panelcontrol_HorizontalVel.Children.Add(lbl_HorizontalVelocityOutputs); panelcontrol_HorizontalVel.Children.Add(lbl_HorizontalVelocityUnits); panelcontrol_displacement.Children.Add(lbl_Displacement); panelcontrol_displacement.Children.Add(lbl_DisplacementOutput); panelcontrol_displacement.Children.Add(lbl_DisplacementUnits); panelcontrol_Time.Children.Add(lbl_Time); panelcontrol_Time.Children.Add(lbl_TimeOutput); panelcontrol_Time.Children.Add(lbl_TimeUnits); StkPnl_Inputs.Children.Add(panelcontrol_Time); StkPnl_Inputs.Children.Add(panelcontrol_CurrentVel); StkPnl_Inputs.Children.Add(panelcontrol_VerticalVel); StkPnl_Inputs.Children.Add(panelcontrol_HorizontalVel); StkPnl_Inputs.Children.Add(panelcontrol_displacement); //databinding Binding(newProjectile, lbl_CurrentVelOutput, "CurrentVelocity"); } 

您收到此错误,因为它不允许从后台线程访问UI( System.Timers.Timer.Elapsed处理程序在后台线程上运行)。 这是因为在WPF中处理UI的所有线程都应该在Single Threaded Apartment(STA)运行以进行同步。 并且,后台工作人员不在STA中运行。

使用DispatcherTimer而不是System.Timers.Timer

MSDN页面的备注部分概述了2个定时器之间的区别。

如果在WPF应用程序中使用System.Timers.Timer,则值得注意的是System.Timers.Timer在与用户界面(UI)线程不同的线程上运行。 为了访问用户界面(UI)线程上的对象,必须使用Invoke或BeginInvoke将操作发布到用户界面(UI)线程的Dispatcher上。

使用与System.Timers.Timer相对的DispatcherTimer的原因是DispatcherTimer在与Dispatcher相同的线程上运行,并且可以在DispatcherTimer上设置DispatcherPriority。