[C#] 3 wątki, przycinanie GUI


(peterkovic) #1

Witam serdecznie,

Robię prostą aplikacje do losowania 3 zestawów liczb, powiedzmy 100,800 i 2000 liczb. Do każdej z ilości mam odrębny wątek, tworzony przy naciśnięciu przycisku:

private void button1_Click(object sender, EventArgs e)
        {
            button2.Text = ("STOP");
            System.Threading.Thread watek_losowanie = new System.Threading.Thread(losowanie);
            System.Threading.Thread watek_losowanie2 = new System.Threading.Thread(losowanie2);
            System.Threading.Thread watek_losowanie3 = new System.Threading.Thread(losowanie3);
                    button1.Enabled = button3.Enabled = false;
                    Active = Active2 = Active3 = true;
                    watek_losowanie.Start();
                    watek_losowanie2.Start();
                    watek_losowanie3.Start(); 
        }

Oraz funkcja losowanie()

private void losowanie()
        {
            while (Active)
            {
                comboBox1.Invoke(new Action(delegate()
                    {
                        ilosc_liczb = Convert.ToInt32(comboBox1.Text);
                    }));
                tablica = new int[ilosc_liczb];
                Random random = new Random();
                for (i = 0; i < ilosc_liczb; i++)
                {
                    if (Active)
                    {
                        tablica[i] = random.Next(Convert.ToInt32(numericUpDown1.Value), Convert.ToInt32(numericUpDown2.Value));
                        textBox1.Invoke(new Action(delegate()
                            {
                                textBox1.AppendText("Liczba nr " + (i+1) + ": " + tablica[i] + "\n");
                            }));
                    }
                }
                Active = false;
            }
        }

Wszystko wygląda ok gdy uruchamiam dwa pierwsze wątki (dla 100 i 800), GUI nie ma przycięć itp. Natomiast gdy odpalam 3 wątek, często przycisk u którego zmieniam Value na "STOP" rzeczywiście zmienia wartość dopiero po pewnym czasie, również możliwość kliknięcia na niego działa z opóźnieniem (zawiesza się chwilowo GUI). Gdy dany wątek się zakończy, zmienna Active odpowiednia dla każdego z wątków zmienia wartość na false i dzięki temu wychodzę z pętli while(Active){} (to jako informacja).


(mr-owl) #2

Witam,

 

Jesteś pewien że tak powinieneś to robić? Zobacz jak działają delegaty i eventy, same wątki umieść w innym miejscu, np w ciele formy, wywołaj je na onclick, samo Invoke wykonuj gdy jest to niezbędne (InvokeRequired), na sieci znajdziesz bardzo dużo przykładów jak to zrobić.

 

Pozdrawiam,

 

mr-owl


(Edgarus) #3

A próbowałeś w pętlach dodać Thread.Sleep(1) ?