BackgrounWorker otwieranie formatki

0

Hallo, chciałbym zapytać o propozycje rozwiązania poniższego problemu.
Aplikacja którą tworzę ma odpytać bazę o zmiany dokonane w przeciągu 5 sek. od aktualnej daty.
Na formatkę wrzuciłem backgroundWorke'ra w metodzie odpowiedzialnej za działanie w tle:
Ten element działa ale tylko w pewnym sensie. Kolejnym warunkiem było w przypadku pobraniu wierszy z bazy danych miała zostać utworzona formatka, ale przez Sleep formatka jest rysowana jest tylko do pewnego stopnia, a później pauza... Chciałem dodać innego backgraounWorkera odpowiedzialnego za otwieranie okna, ale efekt był identyczny...

while ((worker.CancellationPending == false))
{
                
    if (!first)
         System.Threading.Thread.Sleep(5000);
    else
         first = false;

    //Pobranie wierszy w bazie danych.
...
...
...
}
0

Ale chcesz pytać bazę o coś co 5 sekund? To użyj Timera.

0

Nie wiem czy odpytywanie co 5 sek. jest dobrym pomysłem, ale w tej chwili nic innego nie przyszło mi do głowy.
Swoją drogą słyszałem o technice pushUp ale nie wiem czy można ją wykorzystać w C# i MS SQL, a druga rzecz to czy MS SQL sam będzie wstanie się zorientować się, że częstotliwość odpytywania jednej i tej samej tabeli jest duża i będzie trzymał ją w pamięci ram?

0

BackgroundWorker służy do ciągłego wykonania jakiegoś zadania od początku do końca. Jeśli zaś chcesz zrobić coś w pętli co jakiś czas, to powinieneś użyć Timer z Interval w tym przypadku ustawionym na 5000ms.
Co do pytania o MSSQL - prawdopodobnie tak jest.

0

Równie dobrze może to być drugi wątek ze sleepem w środku, czasem to wygodniejsze od timera. A BackgroundWorker to w ogóle już, nawet nie trzeba wiedzieć za dużo jak wielowątkowość działa. Problemem jest to, że formatka jest tworzona także w drugim wątku, a tak nie powinno być.

Wg mnie powinno być tak:

  • BackgroundWorker pyta bazę
  • po uzyskaniu wyników wysyłane jest zdarzenie OnProgressChanged (jest gotowe już, wystarczy wypełnić o ile pamiętam metoda ReportProgress czy jakoś tak)
  • po odebraniu zdarzenia rysowana formatka, już w głównym wątku.

Jednym słowem, zamiast tworzyć nową formatkę po sleepie, raportuj progress i dopiero utwórz formatkę po odebraniu wysłanego zdarzenia przez wątek główny.

Ja bym tu timera nie stosował. I należy się zastanowić, czy jest sens tworzyć formatkę za każdym razem, chyba lepiej mieć ją utworzoną i uaktualniać tylko.

0
othello napisał(a):

Równie dobrze może to być drugi wątek ze sleepem w środku, czasem to wygodniejsze od timera. A BackgroundWorker to w ogóle już, nawet nie trzeba wiedzieć za dużo jak wielowątkowość działa.

Przy Timerze też nie trzeba za bardzo rozumieć wątków, a przy BackgroundWorkerze i tak trzeba będzie dać sleepa.
BackgroundWorker z założenia ma wykonać jakiś skończoną operację, natomiast tutaj chodzi (o ile dobrze zrozumiałem), o robienie czegoś w cyklicznych odstępach w nieskończoność. Potrzebny jest zatem wątek ze Sleepem w środku, albo prościej właśnie Timer.

  • po uzyskaniu wyników wysyłane jest zdarzenie OnProgressChanged (jest gotowe już, wystarczy wypełnić o ile pamiętam metoda ReportProgress czy jakoś tak)

To zdarzenie służy do przesłania informacji o stopniu zaawansowania skończonej operacji w procentach, na pewno będzie tu pasować?

0

To zdarzenie służy do przesłania informacji o stopniu zaawansowania skończonej operacji w procentach, na pewno będzie tu pasować?

Czemu nie? Progress nie musi sie zmieniać, a operacja nie musi się kończyć. Fakt, że mało elegancke, lepiej napisać właśne zdarzenie i użyć Invoke.

Przy Timerze też nie trzeba za bardzo rozumieć wątków, a przy BackgroundWorkerze i tak trzeba będzie dać sleepa.

Aha, to jeszcze uściślijmy który timer. Ten z winforms wykona się w tym samym wątku - na czas operacji na bazie zawiesi cały program. Ten z system.threating wykona sie w oddzielnym wątku. Ale w takim wypadku lepiej i tak użyć wątku ze sleep-em zamiast bujać się ze zdarzeniami timer co ileś sekund, które wykonują się w innym wątku i synchronizować je. Timer nie będzie czekał na kolejny tick, więc jeśli baza przymuli na dłużej niż odstęp między tickami, to wykonają się 2 ticki jednocześnie. Więc trzeba synchronizować i zakładać locka. W przypadku oddzielnego wątku ze sleepem nie ma tego problemu.

Ja jestem zdania, że jeśli coś ma się dziać w tle, to od razu narzuca użycie wątków. A czy tam będzie sleep czy cokolwiek innego, czy wątek ma się konczyć czy nie kończyć to nie ma żadnego znaczenia. Można sobie wrzucić nieskończoną pętlę do oddzielnego wątku, niby czemu nie?

0

To by bylo na tyle...

private System.Timers.Timer _timer = new System.Timers.Timer();
private volatile bool _requestStop = false;

public constructor()
{
    _timer.Interval = 5000;
    _timer.Elapsed += OnTimerElapsed;
    _timer.AutoReset = false;
    _timer.Start();
}

private void OnTimerElapsed(object sender, System.Timers.TimerEventArgs e)
{
    //do work....

    if (!_requestStop)
    {
        _timer.Start();//restart the timer
    }
}

private void Stop()
{
    _requestStop = true;

    _timer.Stop();
}

private void Start()
{
    _requestStop = false;

    _timer.Start();
}

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