Как я могу обработать «CrossThreadMessagingException»?

#c# #multithreading #exception #thread-safety

#c# #многопоточность #исключение #безопасность потоков

Вопрос:

У меня есть простой код для отображения временной последовательности в моем графическом интерфейсе с помощью компонента label. Этот код находится в тиковом событии таймера. Иногда я получаю «Microsoft.VisualStudio.Отладчик.Время выполнения.Исключение CrossThreadMessagingException» и я не понимаю, почему? Как я могу перехватить это исключение? Как я могу изменить свой код, чтобы не получать это исключение?

     //Calculate and show elapsed time
    TimeSpan ElapsedTime = DateTime.Now - this.StartTime;
    this.LabelElapsedTime.Text = String.Format("{0:00}:{1:00}:{2:00}", ElapsedTime.Hours, ElapsedTime.Minutes, ElapsedTime.Seconds);
  

Комментарии:

1. Что такое трассировка стека? Какой таймер?

2. У меня есть только один таймер с интервалом в 1000 миллисекунд.

3. Вы должны использовать a Stopwatch вместо выполнения DateTime.Now - this.StartTime : msdn.microsoft.com/en-us/library /. … Он более точен и предназначен для получения прошедшего времени.

Ответ №1:

Скорее всего, событие таймера обращается к элементу управления из другого потока, например, из таймера.Событие интервала. Чтобы избежать этой проблемы, элемент управления.Должно быть проверено свойство InvokeRequired, и если true, доступ к элементу управления должен выполняться с использованием делегата из элемента управления.Вызов метода.

Примером этого может быть следующее:

 void UpdateLabel(Label lbl, String text)
{
    if (lbl.InvokeRequired)
    { lbl.Invoke(new Action<Label, String>(UpdateLabel), new object[] { lbl, text }); }
    else
    { lbl.Text = text; }
}
  

Комментарии:

1. Почему исключение происходит только иногда, а не каждый раз? Можно было бы подумать, что поток таймера всегда отличается от потока GUI.