如何更新与BackgroundWorker的GUI? [英] How to update GUI with backgroundworker?

查看:104
本文介绍了如何更新与BackgroundWorker的GUI?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我花了一整天试图让我的应用程序使用线程,但没有运气。我读过多文档关于这一点,我仍然得到很多的错误,所以我希望你能帮助我。

I have spent the whole day trying to make my application use threads but with no luck. I have read much documentation about it and I still get lots of errors, so I hope you can help me.

我有调用数据库和更新GUI一大费时的方法。这有可能发生的时间(或大约每30秒)。

I have one big time consuming method which calls the database and updates the GUI. This has to happen all the time(or about every 30 seconds).

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();
    }
}

通过这种方法,我得到一个例外,因为BackgroundWorker的是不是和STA线程(但是从我能理解,这是我应该用什么)。我曾尝试与STA线程,这给了其他错误。

With this approach I get an exception because the backgroundworker is not and STA thread(but from what I can understand this is what I should use). I have tried with a STA thread and that gave other errors.

我认为这个问题是因为我试图在做数据库调用(在后台线程)来更新GUI。我只能做数据库调用,然后莫名其妙就应该切换回主线程。主线程执行后,它应该回到后台线程等等。但我看不出如何做到这一点。

I think the problem is because I try to update the GUI while doing the database call(in the background thread). I should only be doing the database call and then somehow it should switch back to the main thread. After the main thread has executed it should go back to the background thread and so on. But I can't see how to do that.

应用程序应该在数据库调用后立即更新GUI。似乎Firering事件不工作。该backgroundthread刚刚进入他们。

The application should update the GUI right after the database call. Firering events don't seem to work. The backgroundthread just enters them.

编辑:

一些真正伟大的答案:)这是新的code:

Some really great answers :) This is the new code:

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
}

}

但我怎样才能使这个运行,每10第二λ System.Threading.Thread.Sleep(10000)只会使我的GUI冻结,而在所建议的更新()(true)循环给出了一个例外(螺纹太忙)。

But how can I make this run every 10 second? System.Threading.Thread.Sleep(10000) will just make my GUI freeze and while(true) loop in Update() as suggested gives an exception(Thread too busy).

推荐答案

您需要声明,一旦配​​置BackgroundWorker的 - 然后调用你的循环中的RunWorkerAsync方法...

You need to declare and configure the BackgroundWorker once - then Invoke the RunWorkerAsync method within your loop...

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 += new DoWorkEventHandler(backgroundWorker_DoWork);
        _backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker_ProgressChanged);
        _backgroundWorker.WorkerReportsProgress= true;
    }

    public void Update()
    {
         _backgroundWorker.RunWorkerAsync();    
    }

    public void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        while (true)
        {
        // Do the long-duration work here, and optionally
        // send the update back to the UI thread...
        int p = 0;// set your progress if appropriate
        object param = "something"; // use this to pass any additional parameter back to the UI
        _backgroundWorker.ReportProgress(p, param);
        }
    }

    // This event handler updates the UI
    private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        // Update the UI here
//        _userController.UpdateUsersOnMap();
    }
}

这篇关于如何更新与BackgroundWorker的GUI?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆