BackgroundWorker i 2wątki równocześnie

0

Witam,

Próbuję właśnie zrozumieć, jak działają wątki w C#. Załóżmy, że mam na formularzu kontrolkę Label i jeden BackgroundWorker. Działanie wątku polega na zwiększaniu zawartości etykiety, czyli jest coś takiego:

private void thread_DoWork(object sender, DoWorkEventArgs e)
        {
            while (true)
            {
                testGlobals.licznik++;
                testLabel.Text = Convert.ToString(testGlobals.licznik);
                if (thread.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }
            }
         
        }

Uruchamianie wątku:

try
            {
             thread.RunWorkerAsync();
            }


          catch
              {
               MessageBox.Show("Nie można uruchomić wątku");
              }

I zatrzymywanie wątku:

thread.CancelAsync();

Wszystko działa dobrze.

Następnie chciałem utworzyć 2 wątki równocześnie. Dodałem więc drugi komponent BackgroundWorker i wszystko zrobiłem analogicznie.

Ale okazuje się, że nie jest tak łatwo - nie można ot tak sobie uruchomić dwóch watków jednocześnie za pomocą dwóch komponentów BackgroundWorker. Jeżeli spróbuję to zrobić, to wygląda to tak, jakbym w ogóle wątków nie używał - czyli program się zawiesza - w ten sposób może działać tylko jeden wątek.

Jak uruchomić 2 wątki jednocześnie (lub więcej) za pomocą BackgroundWorker? (o ile sie da).

0

wygląda na to, że program sie sypie, bo obydwa wątki w tej samej chwili chcą coś wpisac w zmienną w jeszcze innym wątku. Sam nie próbowałem background workera albe może działać taki patent:
powiedzmy, ze chcesz aby watki dodwały kropkę '.' do labela, albo linijke do listBoxa, albo cos takiego. Musisz zmusic metody doWork do zgłoszenia eventu. W tym celu musisz sobie zdefiniowac EventArgs i EventHandler (chyba, ze nie przesylasz informacji w rodzaju zmiennych, a starczy samo zaistnienie zdarzenia, to wtedy mozesz korzystac z klas macierzystych System.EventArgs i EventHandler. Teraz funkcja która bedzie np właśnie dodawała do listBoxa linijkę w rodzaju 'jakiś wątek coś zrobił':
fukncja musi przyjmowac takie argumenty, zeby pasowała do EventHandlera, jeżeli uzywamy tego podstawowego systemowego EventHandlera, będzie to funkcja(object sender, EventArgs e)

Robimy coś takiego:

private void recv(object sender,MessageReceivedEventArgs e)
        {
            if (this.listBox1.InvokeRequired)
            {
                EventHandler msgcb = new EventHandler(recv);
                this.Invoke(msgcb, new object[] { sender, e });
            }
            else
            {
             
                this.listBox1.Items.Add("-wątek coś zrobił");
            }
            return;

tak po chłopsku:
wątek pyta się wątku głównego (w którym pracuje np listBox) czy może sobie dodać coś do listboxa, czy może na listBoxie ktoś/cos wykonuje już operację i musimy się ustawić w kolejce, czyli wywołać funkcję Invoke, która służy do bezpiecznego wywoływania fukncji z jednego wątku w drugim

w sumie dodanie powyzszego kodu w samej fukncji thread_DoWork też powinno załatwić sprawę, ale wtedy musisz się pogodzić z używaniem DoWorkEventArgs zamiast jakiegos samodzielnie skontruowanego typu pochodnego.

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