Member 11588285 Ответов: 1

C# зависает случайным образом в setmaterialname при получении данных последовательного порта


Привет Я написал приложение Mogre (Managed Ogre) C#.
приложение зависает случайным образом, но не показывает никакого сообщения, просто " не отвечает"
я не уверен, но я предполагаю, что проблема заключается в обработчике Data_Receive последовательного порта.
код этого раздела представлен ниже.



<pre>       public void Open_Port()
        {
            try
            {

                Data_Comport = new SerialPort(PortName, 9600, Parity.None, 8, StopBits.One);
                Data_Comport.ReadTimeout = 5000;
                Data_Comport.WriteTimeout = 5000;
                Data_Comport.DataReceived += new SerialDataReceivedEventHandler(PortDataReceivedHandler);
                Data_Comport.Open();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
        public delegate void InvokeDelegate();
        private void PortDataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
        {
            if (Data_Comport.IsOpen)
            {
                //  try
                //   {
                //var line = Data_Comport.ReadLine();
                bool success = false;
                try
                {
                    success = int.TryParse(Data_Comport.ReadLine().ToString(), out myMogre.finger_id);
                }
                catch (InvalidOperationException ex)
                {
                    MessageBox.Show(ex.ToString());
                }
                catch (TimeoutException ex)
                {
                    MessageBox.Show(ex.ToString());
                }

                if (success)
                {
                    //if (Data_Comport.ReadLine().Contains("-") && myMogre.finger_id == 1)
                    //    myMogre.finger_id = -myMogre.finger_id;
                    Data_Comport.DiscardInBuffer();
                    Data_Comport.DiscardOutBuffer();
                    myMogre.finger_id = myMogre.finger_id - 2;

                    try
                    {
                        if (myMogre.Verified)
                        {
                            for (int i = 0; i < 5; i++)
                            {
                                if (myMogre.finger_id + 2 == i)
                                {
                                    myMogre.Ok_Coin_Entity[i].SetMaterialName("coinsmat/Ok_coin_defok" + i.ToString());
                                }
                                else
                                {
                                    myMogre.Ok_Coin_Entity[i].SetMaterialName("coinsmat/Ok_coin_def" + i.ToString());
                                }
                            }

                            for (int i = 0; i < myMogre.N_of_Coins; i++)
                            {
                                if (myMogre.finger_id == myMogre.Random_Pos[i] && myMogre.Out_coins[i])
                                {
                                    if (!myMogre.long_lines_isselected[i])
                                    {
                                        myMogre.long_lines_Entities[i].SetMaterialName("Long/long_" + (myMogre.Random_Pos[i] + 2).ToString());
                                        myMogre.long_lines_isselected[i] = true;
                                    }
                                }
                                else
                                {
                                    myMogre.long_lines_Entities[i].SetMaterialName("Long/long" + (myMogre.Random_Pos[i] + 2).ToString());
                                }
                            }
                        }
                    }
                    catch (NullReferenceException ex)
                    {
                        MessageBox.Show(ex.ToString());
                    }
                }
                /*                }
                                catch (System.IO.IOException error)
                                {
                                    return;
                                }
                                catch (System.InvalidOperationException error)
                                {
                                    return;
                                }*/
            }
        }


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

и это может быть полезно, что эта функция находится в другом потоке потока Mogre!

Спасибо за ваши предложения!

1 Ответов

Рейтинг:
10

johannesnestler

Таким образом, ваш обработчик работает долго - лучше не позволяйте ему работать на UI-потоке. То, что вы видите, является результатом просмотра Windows вашего "MessageLoop" (старая добрая вещь за механизмом событий Windows)
Если больше никаких сообщений (событий) не обрабатывается, он показывает это сообщение "не отвечает".
Решение: весь ваш datareceiver не должен иметь ничего общего с пользовательским интерфейсом и выполнять всю свою работу в отдельном потоке. Если что - то нужно обновить в пользовательском интерфейсе-создайте событие для вашего компонента dataReceiver (класса) и уведомите об этом пользовательский интерфейс через него.


Member 11588285

Привет.
Спасибо за ваш ответ! это решило мою проблему!
просто переместил часть кода в методе receiver в другой поток!
вы спасли мое время!
большое вам спасибо!

johannesnestler

приятно слышать - добро пожаловать!