KManishS Ответов: 1

Коммуникация Com-порта в C# Ошибка обмена сообщениями между потоками


Всем привет,
Я написал программу, которая считывает данные с com-порта и выполняет дальнейшую обработку. Программа работает хорошо, но иногда она выбрасывает исключение "crossthreadmessaging", когда я присваиваю значение текстовому полю. Мне нужно ваше ценное руководство, чтобы разобраться в этой проблеме.
ниже приведен код, который я использую в своем приложении.

void lobjCOM1_DataReceived(object sender, SerialDataReceivedEventArgs e)
      {

              string lsCOM1Val = lobjCOM1.ReadExisting();

              if (lsCOM1Val.Length > 8)
              {

                  if (lsCOM1Val.Substring(lsCOM1Val.Length - 8, 1) == "H")
                  {
                      if (this.txtC2.InvokeRequired)
                      {
                          this.txtC2.BeginInvoke((MethodInvoker)delegate()
                          {
                              try
                              {
                                  this.txtC2.Text = (Int64.Parse(lsCOM1Val.Substring(lsCOM1Val.Length - 6, 5)) / 1000).ToString() + "." + String.Format("{0:000}", (Int64.Parse(lsCOM1Val.Substring(lsCOM1Val.Length - 6, 5)) % 1000));
                              }
                              catch (FormatException ex)
                              {
                                  this.txtC2.Text = "99.999";
                              }
                          });
                      }


                  }
              }
      }


заранее спасибо...

Что я уже пробовал:

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

1 Ответов

Рейтинг:
1

OriginalGriff

Это очень странно - вы получаете доступ только к текстовому полю внутри делегата, который всегда вызывается, поэтому исключение не должно происходить. И внутри делегата вы ловите исключения, так что вы все равно не должны их видеть.

Но есть пара вещей, чтобы попытаться улучшить ситуацию.
1) Вам не нужен тест InvokeRequired: DataReceived всегда находится в отдельном потоке, он никогда не находится в потоке пользовательского интерфейса - см. документацию: Последовательный порт.Событие DataReceived (Системы.ИО.Порты)[^]
2) Выполняйте весь свой синтаксический анализ в текущем потоке и заставляйте пользовательский интерфейс выполнять только "вызываемый" код - таким образом, ваш пользовательский интерфейс должен оставаться более отзывчивым, поскольку вы минимизируете его работу, если есть много дел.

Так что попробуйте вот так:

void lobjCOM1_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
    string lsCOM1Val = lobjCOM1.ReadExisting();
    if (lsCOM1Val.Length > 8)
        {
        if (lsCOM1Val.Substring(lsCOM1Val.Length - 8, 1) == "H")
            {
            string value = "99.999";
            try
                {
                value = (Int64.Parse(lsCOM1Val.Substring(lsCOM1Val.Length - 6, 5)) / 1000).ToString() + "." + String.Format("{0:000}", (Int64.Parse(lsCOM1Val.Substring(lsCOM1Val.Length - 6, 5)) % 1000));
                }
            catch (FormatException ex) {}
            txtC2.BeginInvoke((MethodInvoker)delegate() { this.txtC2.Text = value; });
            }
        }
    }
Что должно облегчить отладку любых нечетных исключений, которые вы получаете.