2 wątki backgroundworker

0

Gdy miałem jeden backgroundworker w programie było ok, losowanie liczb nie zacinało GUI, a progress bar się "ładował". Uruchamianie wątku odbywało się po przyciśnięciu button1:

private void button1_Click(object sender, EventArgs e)
        {
                button3.Enabled = button1.Enabled = false;
                if (backgroundWorker1.IsBusy != true) 
                {
                    // Start the asynchronous operation.
                    button2.Text = "STOP"; 
                    backgroundWorker1.RunWorkerAsync(); 
                }
        }

Gdy operacje z backgroundworker1 zakończą się, aktywowany jest button3 - sortowanie. I tam kod wygląda niemal identycznie, tylko uruchamiam backgroundworker2:

private void button3_Click(object sender, EventArgs e)
        {
            button3.Enabled = button1.Enabled = false;
            if (backgroundWorker2.IsBusy != true)
            {
                // Start the asynchronous operation.
                button2.Text = "STOP"; 
                backgroundWorker2.RunWorkerAsync(); 
            } 
        }

W chwili obecnej, podczas wykonywania operacji po odpaleniu backgroundworker1 przyciskiem button1, działa jakby nie było wątku, okno GUI jest zamrożone. Wartość w progressBar1.Value którą ustawiam poprzez e.ProgressPercentage, nie ulega zmianie podczas wykonywania wątku.
Po zakończeniu klikam button3 i rozpoczyna prace backgroundworker2, tam operację mogę teoretycznie przerwać (okno nie jest zamrożone), lecz daje to połowiczny efekt - buttony zmieniają właściwości (visable=false na true), ale już wpisy do textBoxów nie wchodzą. Sam wątek też się nie przerywa, tylko liczy do samego końca (tak, stosuję backgroundWorker2.CancelAsync()).
Obydwa backgroundworkery operują na tej samej tablicy, lecz musi zostać ona utworzona w pierwszym wątku, aby drugi mógł coś z nią robić.

0

Pokaż cały kod.

0

Sprawę niezatrzymywania się wątku backgroundworker2 rozwiązałem, lecz dalej mam problem z zamrażaniem GUI dla backgroundworker1.
Pokaże najważniejsze wycinki kodu:

        public Form1()
        {
            InitializeComponent();
            backgroundWorker1.WorkerReportsProgress = true;
            backgroundWorker1.WorkerSupportsCancellation = true;
            backgroundWorker2.WorkerReportsProgress = true;
            backgroundWorker2.WorkerSupportsCancellation = true;
        }

Kod button1 + backgroundworker1

private void button1_Click(object sender, EventArgs e)
        {
                button3.Enabled = button1.Enabled = false;
                if (backgroundWorker1.IsBusy != true) //jeżeli background1 nie pracuje...
                {
                    // Start the asynchronous operation.
                    button2.Text = "STOP"; 
                    backgroundWorker1.RunWorkerAsync(); 
                }
        }

 private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;	
            ...
                    if (worker.CancellationPending == true) 
                    {
                        e.Cancel = true; 
                        break;
                    }
                    else 
                    {
						...
                        worker.ReportProgress(Convert.ToInt32(procent), new Klasa_doProgressReport_losowanie() { wartoscI = i, Liczba_wylosowana = liczba_w_string });
                        System.Threading.Thread.Sleep(1);
                    }
                }
        }



private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            var Klasa_doProgressReport_losowanie = e.UserState as Klasa_doProgressReport_losowanie;
            progressBar1.Value = e.ProgressPercentage; 
			...
        }


private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled == true) 
            {
                procent = 0; 
                button1.Enabled = true;
                button3.Enabled = false;
            }
            else 
            {
                button1.Enabled = button3.Enabled= true;
                button2.Text = "Koniec"; 
                procent = 0;
            }
        }

Button3 + backgroundworker2

        private void button3_Click(object sender, EventArgs e)
        {
            if (backgroundWorker2.IsBusy != true) 
            {
                // Start the asynchronous operation.
                button2.Text = "STOP"; 
                backgroundWorker2.RunWorkerAsync(); 
            } 
        }

private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker2 = sender as BackgroundWorker;
			...
			do 
                {
                    if (worker2.CancellationPending == true) /
                    {
                        e.Cancel = true; 
                        break; 
                    }
                    else
                    {
                        zamiana = 0;
                        for (int i = 0; i < ilosc_liczb - 1; i++)
                        {
                            if (tablica[i] > tablica[i + 1])
                            {
								zmienna++;
								...
								worker2.ReportProgress(0, new Klasa_do_sortowania() { Liczba_zam1 = liczba_w_string, Liczba_zam2 = liczba_zam_w_string, czas1 = czas1_string });
                                System.Threading.Thread.Sleep(1);
                            }
                        }
						...
                    }
                }
                while (zamiana != 0);
				...
        }

		
		
		
		
private void backgroundWorker2_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            var Klasa_do_sortowania = e.UserState as Klasa_do_sortowania;
			...
		}
		
		
private void backgroundWorker2_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            var Klasa_do_sortowania = e.UserState as Klasa_do_sortowania;
            if (e.Cancelled == true) 
            {
                button1.Enabled = true;
                button3.Enabled = false;
				...            
			}
            else 
            {
                button1.Enabled = button3.Enabled = true;
                button2.Text = "Koniec";
				...
            }

        }

Oraz button2 którego przyciśnięcie powoduje przerwanie wątku:

        private void button2_Click(object sender, EventArgs e)
        {
            if ((backgroundWorker1.WorkerSupportsCancellation == true | backgroundWorker2.WorkerSupportsCancellation==true)& button2.Text == "STOP")
            {
                // Cancel the asynchronous operation.
                button2.Text = "Koniec";
                button1.Enabled = true;
                backgroundWorker1.CancelAsync(); 
                backgroundWorker2.CancelAsync();
            }
            else if ((backgroundWorker1.WorkerSupportsCancellation == true | backgroundWorker2.WorkerSupportsCancellation==true) & button2.Text == "Koniec")
            {
                Application.Exit(); 
            }
            else
            {
                MessageBox.Show("inny przypadek!!! TEST");
            }
        }
0

Nie wiem czy to dobry sposób, ale poczyniłem takie zmiany:

public Form1()
        {
            InitializeComponent();
        }


private void button1_Click(object sender, EventArgs e)
        {
            button3.Enabled = button1.Enabled = false;

            backgroundWorker1.WorkerReportsProgress = true;
            backgroundWorker1.WorkerSupportsCancellation = true;

            BackgroundWorker worker = new BackgroundWorker();
            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
            worker.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
            worker.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);

                if (backgroundWorker1.IsBusy != true) 
                {
                    // Start the asynchronous operation.
                    button2.Text = "STOP"; 
                    backgroundWorker1.RunWorkerAsync(); 
                }
        }


private void button3_Click(object sender, EventArgs e)
        {
            button3.Enabled = button1.Enabled = false;

            backgroundWorker2.WorkerReportsProgress = true;
            backgroundWorker2.WorkerSupportsCancellation = true;

            BackgroundWorker worker2 = new BackgroundWorker();
            worker2.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker2_RunWorkerCompleted);
            worker2.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker2_ProgressChanged);
            worker2.DoWork += new DoWorkEventHandler(backgroundWorker2_DoWork);

            if (backgroundWorker2.IsBusy != true) 
            {
                // Start the asynchronous operation.
                button2.Text = "STOP"; 
                backgroundWorker2.RunWorkerAsync(); 
            } 
        }

Niby działa dobrze. Czy ktoś może zweryfikować?

0

Cóż sprawdziłem na komputerze w pracy i tu niestety wszystko jest jakby na jednym wątku...

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