Wielowątkowość a komponenty

0

Witam,
napisałem taki oto prosty kod, który ma "rozwijać" panel:

delegate void Delegat();
        private void button1_Click(object sender, EventArgs e)
        {
            panel1.BackColor = Color.Red;
            panel1.Height = 0;

            System.Threading.Thread t = new System.Threading.Thread(() =>
                {
                    if (panel1.InvokeRequired)
                    {
                        panel1.Invoke((Delegat)delegate
                        {
                            for (int i = 0; i < 30; i++)
                            {
                                panel1.Height += 5;
                                System.Threading.Thread.Sleep(100);
                            }
                        });
                    }
                });
            t.Start();

        }

wszystko ładnie wygląda, panel jest w miare płynnie rysowany, ale... podczas rozwijania panelu(czyli na te 3 sekundy) blokowana jest cała aplikacja, to znaczy nie mozna jej przesuwać, klikać buttonów znajdujących się na formie itp.
Moje pytanie brzmi: Dla czego? Przecież jest to osobny wątek?
I jak temu zaradzić?
Z góry dzięki za pomoc:)

0

przez invoke masz TYLKO zmieniać rozmiar a nie robić w nim wszystko

0

Czyli rozwijając myśl Misiekd'a pętle i sleep musisz mieć w osobnym wątku.

0

o, wielkie dzięki:)

a jeszcze przy okazji. może ktoś mi wytłumaczyć jaka jest różnica pomiędzy Thread a Task?

0

czy ty rozumiesz w ogóle co ty zrobiłeś?

  1. button1_Click wywoływane jest z wątku UI.
  2. Tworzysz nowy wątek,
  3. następnie wywołujesz z niego invoke, które zatrzymuje stworzony wątek
  4. invoke powoduje, że wątek czeka na event loop-a wątku UI i wykonuje delegata w wątku UI,
  5. po wykonaniu delegata wątek, który wywołał invoke jest wznawiany.
    ergo twój wątek nie ma żadnej funkcjonalności!
    Czy nie prościej wykorzystać timer i nie bawić się w wątki?
    Względnie czy przypadkiem nie ma gotowej biblioteki do robienia animacji UI?
0

ok, swój błąd już zrozumiałem. ale teraz powiedz mi, co za różnica czy zrobie to na wątkach czy na timerze?

0

Do pytania: jaka jest różnica pomiędzy Thread a Task?
Jeśli masz na myśli Task w rozumieniu biblioteki Parallel Library, to jest to zadanie do wykonania, które zostanie wykonane przez jeden z wątków roboczych. Samymi wątkami i podziałem zadań zarządza biblioteka.

Na timerze raczej prościej, bo tylko konfigurujesz interwał timera i odpalasz, a później na tick wykonujesz zmianę gui (jeden krok). Pamiętaj że metoda obsługi tick, jest w kontekście innego wątku niż gui.
Jeśli użyjesz wątku stworzonego przez siebie, efekt będzie podobny, ale pewnie wyjdzie ci więcej kodu.

0
massther napisał(a)

Pamiętaj że metoda obsługi tick, jest w kontekście innego wątku niż gui.

Zależy od Timer'a.
System.Windows.Forms.Timer - działa w tym samym wątku co UI
System.Threading.Timer - korzysta z "thread pool".

1

aha, czyli timer(w moim przypadku oczywiście) różni się od wykorzystania wątków tylko ilością kodu? chyba pomimo wszystko zostane przy wątkach. Dzięki za pomoc:)

0

mam jeszcze jedno pytanie...
jeśli mam kod w wątku:


label1.Text = "Hej";
label2.Text = "Co słychać?";
 

to czy dla obu komponentów muszę robić Invoke osobno? tak jak tutaj:

 
if (label1.InvokeRequired)
                    label1.Invoke((Deleg)delegate
                    {
                        label1.Text = "Hej";
                    });

if (label2.InvokeRequired)
                    label2.Invoke((Deleg)delegate
                    {
                        label2.Text = "Co słychać?";
                    });

nie da się zrobić tak, aby sprawę załatwiało jedno Invoke?

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