C#, odwołanie do kontrolki z innego wątku

0

Ja tylko w kwestii formalnej, bo oczywiście wiem jak się to robi. Załóżmy sobie, że wątek ma zrobić coś takiego:

for(int i=0 ; i< 10 ; i++)
{
 Sleep(1000);
 //Ustaw label1 na bieżącą wartość i
}  

a następnie skończyć się.

Teraz: jak uważacie, czy taki kod realizujący zadanie:

 new Thread(new ThreadStart(()=>
            {
                for(int i=0;i<10;i++)
                {
                    Thread.Sleep(1000);
                    if (label1.InvokeRequired) label1.Invoke((MethodInvoker)(() => { label1.Text = i.ToString(); }));
                    else label1.Text = i.ToString();                   
                }
            })).Start(); 

to wg was dobre podejście do tematu czy nie i dlaczego? Chodzi o filozofię umieszczenia "wszystkiego w jednym miejscu", kod działa oczywiście ale zastanawiam się czy powinno się tak robić?

0

imho po to wprowadzili właśnie wyrażenia lambda żeby z nich korzystać
byle znowu nie przesadzać i nie pisać w ten sposób kilkudziesięcio-liniowych funkcji

mi się osobiście takie coś bardzo podoba i wydaje mi się bardzo czytelnie
a na pewno czytelniejsze niż wydzielenie tego do osobnego pliku czy też nawet kilku plików

ale ja mogę mieć spaczoną psychikę przez dużą ilość kodu napisanego w javascript ;)

a tak już czepiając się konkretnie tego kodu:

  1. przez lambdę musiałeś złamać zasadę DRY
  2. sprawdzanie InvokeRequired jest w ogóle niepotrzebne - przecież widać na pierwszy rzut oka że ten label nie należy do tego wątku więc zawsze zwróci true
  3. nie reagujesz na prośby uśpienia wątku - jeżeli od razu po uruchomieniu dodatkowego wątku zamkniesz program to będzie on pracował niepotrzebnie jeszcze przez 10 sekund...
0

sprawdzanie InvokeRequired jest w ogóle niepotrzebne - przecież widać na pierwszy rzut oka że ten label nie należy do tego wątku więc zawsze zwróci true

Tak, ale bez InvokeRequired, gdy zamkniemy program to zamiast czekać na zakończenie wątku, Invoke sypnie wyjątkiem.

nie reagujesz na prośby uśpienia wątku - jeżeli od razu po uruchomieniu dodatkowego wątku zamkniesz program to będzie on pracował niepotrzebnie jeszcze przez 10 sekund...

Zdaję sobie z tego sprawę. To jedynie przykład, poza tym - czasem lepiej jest zaczekać z zamknięciem programu do czasu aż wszystkie wątki się zakończą, zależy co robi ten wątek.

Ogólnie, zadaję takie pytanie bo z tego co widzę prawie nikt tak nie pisze - każdy deklaruje co najmniej oddzielną metodę na threadstard, delegaty anonimowe i lambda też nie są za bardzo popularne. A mi też taki zapis się o wiele bardziej podoba, bo od razu wszystko widać - wszystko w jednej metodzie, jak dla mnie bardziej przejrzyste i łatwe do ogarnięcia wzrokiem.

0

Ja bym raczej odpalił ten wątek w innej klasie, która rzuci zdarzeniem, a do tego zdarzenia podpiął metodę z klasy okienka, która zrobi co trzeba w GUI.

0

No tak jak pisałem, kwestia podejścia do sprawy i tak zastanawiam się co jest lepsze - deklarować "tradycyjnie" delegaty i zdarzenia, czy wszystko zagnieżdżone w jednej metodzie tak jak podałem w tym przykładzie.

1

Visual 2012:

async void Bubu()
{
  for(int i=0 ; i< 10 ; i++)
  {
    await TaskEx.Delay(1000);
    //Ustaw label1 na bieżącą wartość i
  }
}

i nie trzeba do tego wątków.

0

Fajne

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