Jak zaktualizować GUI za pomocą backgroundworker?
Spędziłem cały dzień, starając się, aby moja aplikacja korzystała z wątków, ale bez powodzenia. Przeczytałem dużo dokumentacji na ten temat i wciąż mam wiele błędów, więc mam nadzieję, że możesz mi pomóc.
Mam jedną dużą, czasochłonną metodę, która wywołuje bazę danych i aktualizuje GUI. To musi się zdarzyć cały czas (lub mniej więcej co 30 sekund).
public class UpdateController
{
private UserController _userController;
public UpdateController(LoginController loginController, UserController userController)
{
_userController = userController;
loginController.LoginEvent += Update;
}
public void Update()
{
BackgroundWorker backgroundWorker = new BackgroundWorker();
while(true)
{
backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);
backgroundWorker.RunWorkerAsync();
}
}
public void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
_userController.UpdateUsersOnMap();
}
}
Dzięki takiemu podejściu otrzymuję wyjątek, ponieważ backgroundworker nie jest i wątkiem STA (ale z tego, co rozumiem, to powinienem używać). Próbowałem z wątkiem STA, który dał inne błędy.
Myślę, że problem polega na tym, że próbuję zaktualizować GUI podczas wykonywania wywołania bazy danych (w wątku w tle). Powinienem wykonywać tylko wywołanie bazy danych, a następnie jakoś powinien wrócić do głównego wątku. Po wykonaniu głównego wątku powinien powrócić do wątku tła i tak dalej. Ale nie widzę, jak to zrobić.
Aplikacja powinna zaktualizować GUI zaraz po wywołaniu bazy danych. Zdarzenia ognia nie działają. Wątek tła właśnie je wprowadza.
EDYTOWAĆ:
Kilka naprawdę świetnych odpowiedzi :) To jest nowy kod:
public class UpdateController{
private UserController _userController;
private BackgroundWorker _backgroundWorker;
public UpdateController(LoginController loginController, UserController userController)
{
_userController = userController;
loginController.LoginEvent += Update;
_backgroundWorker = new BackgroundWorker();
_backgroundWorker.DoWork += backgroundWorker_DoWork;
_backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted;
}
public void _backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
_userController.UpdateUsersOnMap();
}
public void Update()
{
_backgroundWorker.RunWorkerAsync();
}
void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//UI update
System.Threading.Thread.Sleep(10000);
Update();
}
public void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
// Big database task
}
}
Ale jak mogę to uruchomić co 10 sekund? System.Threading.Thread.Sleep (10000) sprawi, że mój GUI zostanie zablokowany, a pętla (true) w Update (), jak zasugerował, daje wyjątek (wątek zbyt zajęty).