Blokowanie formy

0

Witam!

Mam następujący problem:
Piszę aplikację desktopową,która ma na celu okresowo odpytywać pewne urządzenia po TCP oraz ich poszczególne parametry, aktualny stan wyświetlać w DataGridView. Do urządzeń tych dołączona jest dll-ka napisana w Delphi, także poszczególne funkcje odpytujące urządzenia zaimportowane są z biblioteki. Posiadam klasę urządzenia która w przypadku dołączenia nowego urządzenia do monitorowania tworzy w konstruktorze nowy wątek dla tego urządzenia w którym odpytuje go okresowo.

Thread backgroudThread = null;
private static object threadLock = new object();

public konstruktor()
        {
                backgroudThread = new Thread(new ThreadStart(RefreshData));
                backgroudThread.IsBackground = true;
                backgroudThread.Start();
        }


public void RefreshData()
{
     do
        {
                lock (threadLock)
                {
                    funkcjaKomunikacjiZUrzadzeniemZDllki();
                    Thread.Sleep(10);
                     innaFunkcjaKomunikacjiZUrzadzeniemZDllki();
                    Thread.Sleep(10);                 
                     refreshTable();
                 }
          } while (true);

}

Problem polega na tym, że aplikacja zawiesza się w przypadku aktualizacji pól DataGridView funkcją RefreshTable() (która aktualizuje pola DataGridView za pomocą Invoke oraz dodaje nowe wiersze do tabeli za pomocą Invoke). Bardziej bolesne jest to, że mogę pól tabeli nie aktualizować (DataGridView pozostaje puste) a jedynie w wątkach odpytywać poszczególne urządzenia (wieć nie modyfikuje stanu kontrolek), a mimo to w przypadku robienia czegoś w aplikacji np. częstego rozwijania menu strip aplikacja również się zawiesza. Gdy nie robię nic a jedynie odpytuje urządzenia to aplikacja działa bez problemów. DataGridView nie jest podpięte do żadnego DataSource, ale w przypadku nie modyfikowania kontrolek to chyba nie ma znaczenia a aplikacja mimo to się zawiesza, wystarczy kilka razy rozwinąć menu strip.
Proszę o pomoc. Może ktoś z was zna dobre narzędzie do monitorowania wątków aplikacji C#(korzystam z C# express oraz SharpDevelope)

0

a RefreshData() z tymi "pieknymi" sleep'ami chodzi w watku glownym? jesli tak to masz odp.

0

rozumiem, że funkcja RefreshData() coś tam sobie z urzadzenia zew. czyta. W takim wypadku niepotrzebny jest lock (chyba), zamiast sleepów może lepiej skorzystać z timera? a jeżeli chcesz coś uaktualniać na formie to najprościej jest w tym nowym wątku zrobić zdarzenie wywoływane w momencie jak będą nowe dane i do tego zdarzenia się podpiąć z formy. Tak mi się zdaje

0

Witam.

Dzięki za odpowiedzi. Znalazłem dwie przyczyny zwieszania się formy. Pierwsza była związana bezpośrednio z odczytem danych z urządzeń, i ten problem usunąłem. Jednak pozostał jeszcze jeden problem mianowicie forma zawiesza się w przypadku ustawienia właściwości AutoSize: All Cells w kontrolce DataGridView. Zawiesza się w różnych momentach działania aplikacji, jednak najczęściej podczas dodawania nowego wiersza z danymi. Co z tym zrobić? Proszę również o wyjaśnienie dlaczego używanie Thread.Sleep nie jest dobrym stylem programowania.

Pozdrawiam

0

Bez wgłębiania się w szczegóły - musisz podzielic program na 2 warstwy.

Pierwsza, działająca w oddzielnym wątku robi wszystko poza uaktualnianiem wyglądu gui - tam możesz wstawiać swoje sleep-y, odczytywanie danych z urządzenia i co tylko jeszcze chcesz.

Druga warstwa odpowiada za wygląd aplikacji - jest to główny wątek. Jedyne co dzieje się w głównym wątku to uaktualnienie twojego DataGridView danymi otrzymanymi za pomocą eventa z wątku pobocznego (kłaniają się delegaty, eventy i Invoke). Tylko musisz pamiętać, że eventy nie mogą iśc za często, bo jeżeli będziessz wysyłać event co 0.1 sekundy to też apliakcję zawiesisz.

Możesz sobie zadanie nieco uprościć korzystając z kontrolki BackgroundWorker - wtedy nie potrzebujesz delegatów, invoke, wątków bo wszystko masz już gotowe praktycznie.

1

Proszę również o wyjaśnienie dlaczego używanie Thread.Sleep nie jest dobrym stylem programowania.

Bo thread.Sleep usypia cały wątek. Stwórz sobie jakiś projekt i wpisz gdzieś thread.Sleep(100000); - zrozumiesz...

1 użytkowników online, w tym zalogowanych: 0, gości: 1