Como atualizar GUI com backgroundworker?
Eu passei o dia inteiro tentando fazer meu aplicativo usar threads, mas sem sorte. Eu li muita documentação sobre isso e ainda recebo muitos erros, então espero que você possa me ajudar.
Eu tenho um grande método demorado que chama o banco de dados e atualiza a GUI. Isso tem que acontecer o tempo todo (ou a cada 30 segundos).
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();
}
}
Com esta abordagem eu recebo uma exceção porque o backgroundworker não é e STA thread (mas pelo que eu posso entender é isso que eu deveria usar). Eu tentei com um segmento STA e que deu outros erros.
Eu acho que o problema é porque eu tento atualizar a GUI ao fazer a chamada do banco de dados (no segmento de fundo). Eu só deveria estar fazendo a chamada do banco de dados e, em seguida, de alguma forma, ele deve voltar para o thread principal. Depois que o thread principal é executado, ele deve voltar para o thread de segundo plano e assim por diante. Mas não consigo ver como fazer isso.
O aplicativo deve atualizar a GUI logo após a chamada do banco de dados. Firering eventos parecem não funcionar. O backgroundthread apenas entra neles.
EDITAR:
Algumas ótimas respostas :) Este é o novo código:
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
}
}
Mas como posso fazer isso a cada 10 segundos? System.Threading.Thread.Sleep (10000) apenas fará meu congelamento de GUI e while (true) loop em Update () como sugerido dá uma exceção (Thread muito ocupado).