BackgroundWorker czy zakończy się sam ?

0

Witam. Jestem początkujący i mam pytanie odnośnie BackgroundWorker'a. Chodzi o to czy jeśli zniszcze (Dispose) obiekt w którym stworzyłem inny obiekt a w nim BackgroundWorkera to czy ten ten BackGroundWorker automatycznie się przerwie? Działa on w pętli nieskończonej monitorując kontrolki, które są UserControl. Na mocnym procku (i7) jest wszysytko ok. Problem jest na słabszym bo program obciąża mocno procesor (90 %). I nie zmienia się to nawet jeśli zniszczę UserControl. Wiem że mogę go przerwać (CancelAsync), ale muszę mieć bezpośredni dostęp do zmiennej backgroundworkera a z tym trochę gorzej.

0

nie. Pętla metody DoWork nie powinna być nieskończona. Powinieneś przynajmniej sprawdzać czy wątek nie został zastopowany metodą CancelAsync przez sprawdzanie właściwości CancellationPending, przykład https://msdn.microsoft.com/pl-pl/library/system.componentmodel.backgroundworker.cancellationpending(v=vs.110).aspx

BTW jak Twój wątek obciąża procesor na 90% a nie wykonuje jakichś skomplikowanych zadań to masz w nim coś zwalone.

0

To jest pętla nieskonczona która przechodzi po wszystkich Burtona w danym panelu i porównuje dane z baza. Czyli są tam dwie pętle ta wewnątrz to foreach i ona sprawdza każdy button. Jak zwiększyłem thread.sleep to problem obciążenia zniknal

0

bg raczej nie zakończy się sam, spróbuj coś takiego:

przy pętli nieskończonej dodaj sprawdzanie czy bacground

class FakeComponet : IDisposable
    {
        private BackgroundWorker bg = new BackgroundWorker();

        public FakeComponet()
        {
            bg.WorkerSupportsCancellation = true;
            bg.WorkerReportsProgress = true;
            bg.DoWork += Bg_DoWork;
            bg.ProgressChanged += Bg_ProgressChanged;
        }

        private void Bg_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            Console.WriteLine(e.UserState);
        }

        public void StartAsync()
        {
            bg.RunWorkerAsync();
        }

        private void Bg_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            while (true)
            {
                if (worker.CancellationPending)
                {
                    e.Cancel = true;
                    break;
                }
                System.Threading.Thread.Sleep(1000);
                worker.ReportProgress(0, DateTime.Now);
            }
        }

        public void Dispose()
        {
            if (bg != null && bg.IsBusy)
            {
                bg.CancelAsync();
            }
        }
    }

Powinno udać Ci się przeciążyć, albo zaimplementować Dispose dla komponentu który ma bg i tam to anulować. Bez tego, to raczej długo będzie bg działał.
Bardzo prosto to sprawdzić jak dasz sobie System.Console.Beep(); w pętli workera.

0

bg.CancelAsync(); NIC NIE DA jeśli nie obsłuży tego po stronie wątku

1
abrakadaber napisał(a):

bg.CancelAsync(); NIC NIE DA jeśli nie obsłuży tego po stronie wątku

Obsługa jest w wątku

if (worker.CancellationPending)
                {
                    e.Cancel = true;
                    break;
                }
0

rzeczywiście - nie zauważyłem.

0

Problem już rozwiązany. Jako że miałem kilka wątków to zrobiłem klasę singletona która zawiera listę wszystkich wątków. Po wyjściu z danego okna wywołuje dla wszystkich elementów listy CancelAsync.

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