2014-11-29 5 views
-1

Я пытаюсь смоделировать снаряд и пытаться создать метки в событии по времени только один раз, потому что у него есть объект в параметре, который мне нужно быть в событии с таймером. Но я получаю эту ошибку при запуске, когда я запускаю ее. Помоги пожалуйста!Вызов темы должен быть 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"); 
    } 
+0

99.9% этого кода не имеет значения. Отсутствует информация о типе таймера и т. Д. Он должен быть выведен из «ElapsedEventArgs» –

+0

aTimer = новый System.Timers.Timer (200); aTimer.Elapsed + = onTimedEvent; aTimer.Enabled = true; aTimer.Elapsed + = onTimedEvent; aTimer.Enabled = true; – ObnoxiousFrog

+1

Код пользовательского интерфейса должен быть выполнен в пользовательской (главной) теме. Используйте DispatcherTimer. –

ответ

2

Вы получаете эту ошибку, потому что он не имеет доступа пользовательского интерфейса из фонового потока (System.Timers.Timer.Elapsed обработчик работает в фоновом потоке). Это связано с тем, что весь поток, который обрабатывает UI в WPF, должен выполняться в Single Threaded Apartment(STA) для синхронизации. И фоновые работники не работают в STA.

Используйте DispatcherTimer, а не System.Timers.Timer.

Раздел примечаний на странице MSDN описывает разницу между двумя таймерами.

Если System.Timers.Timer используется в приложении WPF, стоит отметить, что System.Timers.Timer работает в другом потоке, то пользовательский интерфейс (UI) потоков. Чтобы получить доступ к объектам в потоке пользовательского интерфейса (UI), необходимо отправить операцию в поток Диспетчер потока пользовательского интерфейса (UI) с помощью Invoke или BeginInvoke.

Причины использования DispatcherTimer, противоположного System.Timers.Timer, состоят в том, что DispatcherTimer работает в том же потоке, что и Dispatcher, и DispatcherPriority можно установить на DispatcherTimer.

+1

Это может помочь другим, если вы добавите причину возникновения этой ошибки. –

+0

ok, добавлено, далее редактирование приветствуется. – kennyzx

+1

После редактирования вопроса: CreateLabels - это все, что делает Timer. Использование Timers.Timer, а затем marshall все работы обратно ерунда. –