• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Przycinanie aplikacji przy rozłączaniu portu szeregowego Visual C#

VPS Starter Arubacloud
0 głosów
208 wizyt
pytanie zadane 22 marca 2021 w C# przez muzyk Użytkownik (940 p.)

Witam serdecznie,

Mam problem z moją aplikacją. Ogólny zamysł jest taki, że próbuję komunikować się z portem, szeregowym i wszystko śmiga elegancko do momentu próby rozłączenia z portem.

Z portem łączę się po wciśnięciu przycisku (Otwórz):

        private void buttonOtworz_Click(object sender, EventArgs e)
        {
            try
            {
                
                serialPort.PortName = cBoxPorts.Text;
                serialPort.Open();

                // Czyszczenie listy poprzednich urzadzen
                  {...}

                // Wysłanie ustawień początkowych aplikacji
                 {...}

                progressBarCOM.Value = 90;

                // Włączanie/wyłączanie przycisków

                 {...}

                // Rozpoczęcie pobierania danych
                Communication.Read(serialPort);

                progressBarCOM.Value = 100;
            }
            catch (Exception exc)
            {
               // Wyświetlenie informacji o błędzie
            }
        }

Aplikacja komunikuje się z płytką, posiada kilka pól wyboru, i przycisków, które po otwarciu połączenia blokuję parametrem Enable = false {poukrywałem zbędne elementy}

Zaraz po połączeniu się z portem rozpoczyna prace background worker, który jest zapętlony i asynchronicznie odbiera dane poprzez metodę Read(). Ustawiłem parametr WorkerSupportsCancellation = true.

Do tego momentu wszystkie funkcjonalności działają poprawnie. Gdy chcę natomiast rozłączyć port (przycisk Zamknij):

 private void buttonZamknij_Click(object sender, EventArgs e)
        {
            // Wstrzymanie wstrzymania informacji przez płytkę
        {...}

            Communication.StopReceive(); 

            if (serialPort.IsOpen)
            {
                serialPort.DiscardInBuffer();
                serialPort.DiscardOutBuffer();
                serialPort.Close();
            }

            // Włączanie/wyłączanie przycisków
          {...}
            // Blokowanie groupBoxów
            {..}
        }

 

Metoda Communication.StopReceive:

        public static void StopReceive()
        {
            if (bgWorkReceive != null && bgWorkReceive.IsBusy)
                bgWorkReceive.CancelAsync();
        }

I po kliknięciu przycisku "Zamknij" aplikacja się bardzo przycina. Wykorzystuję m. in. obiekt klasy TabControl. i gdy przechodzę do innej zakładki to dosłownie piksele ładują się linia po linii. Nie bardzo rozumiem z czego wynika ten problem.

komentarz 22 marca 2021 przez Paweł Nyczkowski Obywatel (1,620 p.)
anulowany

1 odpowiedź

0 głosów
odpowiedź 22 marca 2021 przez Paweł Nyczkowski Obywatel (1,620 p.)
wybrane 22 marca 2021 przez muzyk
 
Najlepsza

jakie masz ustawione timeout dla Read z portu com?

dodaj zmienna semafor, którą ustawisz na true gdy chcesz zakończyć czytanie
ustawienie jej powoduje wyjście z background worker a w zdarzenie btn_zamknij czekasz aż zakończy prace w tle

public bool semafor = false;
private void bgWorkReceive_DoWork(object sender, DoWorkEventArgs e)
{
  while (!semafor)
  {
    //czytanie z portu        
  }
}
 
private void buttonZamknij_Click(object sender, EventArgs e)
{
  semafor = true;
 
  while (bgWorkReceive.IsBusy)
  {/*czekanie aż skończy czytać*/
    System.Threading.Thread.Sleep(100);
  }
  ....
}

czytanie z portu COM może zablokować cały interfejs niezależnie od mocy kompa

komentarz 22 marca 2021 przez muzyk Użytkownik (940 p.)
Zrobiłem zgodnie ze wskazówkami. Faktycznie problem leżał w tym, że bgWorker nie kończył pracy, ponieważ oczekiwał nieskończenie długo na dane w buforze, których nie miało prawa być.

Pojawił się z kolei problem, że pomimo ustawienia semafora zgodnie ze wskazówką i zakończeniu pętli while, a co za tym idzie skończeniu wykonania działanie przez bgWorker parametr IsBusy wciąż zwraca wartość true. Nie wiem niestety dlaczego. Sprawdzałem krok po kroku, wychodzi z metody "DoWork" i wciąż jest zajęty...
komentarz 22 marca 2021 przez muzyk Użytkownik (940 p.)
Powiem tak... Nasuwa mi się cytat z filmu "Ja, Robot" "W maszynach siedzą duchy...".

Usunąłem timeout wątku, bez zmian. Następnie przeniosłem przypisanie semafor = false po rozłączeniu portu, żeby mógł ponownie się zapętlać po połączeniu z przycisku "Zamknij" do przycisku "Otwórz" co teoretycznie ma takie samo działanie i pomogło...
komentarz 22 marca 2021 przez muzyk Użytkownik (940 p.)

I dziękuję oczywiście bardzo za pomoc. Była bardzo przydatna w odnalezieniu źródła kłopotów. wink

Podobne pytania

0 głosów
0 odpowiedzi 149 wizyt
pytanie zadane 9 kwietnia 2019 w Inne języki przez muzyk Użytkownik (940 p.)
0 głosów
1 odpowiedź 137 wizyt
pytanie zadane 17 marca 2019 w C i C++ przez muzyk Użytkownik (940 p.)
0 głosów
2 odpowiedzi 1,503 wizyt
pytanie zadane 26 maja 2015 w C i C++ przez Marcin Nowicjusz (210 p.)

92,840 zapytań

141,781 odpowiedzi

320,856 komentarzy

62,172 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...