Backgroundworker总是很忙

时间:2013-07-11 14:43:16

标签: c# event-handling backgroundworker

我是新手使用事件处理程序和后台工作者,因此我可能会遗漏一些完全明显的东西。不过,我一直试图解决这个问题两天,所以我想我也可以看看有什么人要说的。

我有一个名为SqlExpressDownloader的后台工作程序。它在我的程序开始时运行,其余的工作运行,然后它应该等待SqlExpressDownloader_DoWork()方法中的操作完成后再继续。唯一的问题是,出于某种原因,每当我做while(SqlExpressDownloader.IsBusy)时,它总是响应为忙,因此将永远等待。

事件处理程序的代码在这里:

    private void SqlExpressDownloader_DoWork(object sender, DoWorkEventArgs e)
    {
        string sSource = string.Format("{0}\\{1}", Paths.Settings_Common, "sqlexpr_x64_enu.exe");
        Debug.WriteLine(sSource);
        Debug.WriteLine("http://www.elexioamp.com/Install/redistributables/sql2008r2express/sqlexpr_x64_enu.exe");
        if (!System.IO.File.Exists(sSource))
        {
            WebClient oWebClient = new WebClient();
            oWebClient.DownloadProgressChanged += DownloadProgressChanged;
            oWebClient.DownloadDataCompleted += DownloadComplete;

            oWebClient.DownloadFileAsync(new System.Uri("http://www.elexioamp.com/Install/redistributables/sql2008r2express/sqlexpr_x64_enu.exe"), sSource);

            while (oWebClient.IsBusy)
            {
                Thread.Sleep(100);
            }

            e.Result = "";
            DownloadFinished = true;
        }
    }

我已经看过代码并看过它完成了这个方法。我甚至在return之后添加了DownloadFinished = true,但它仍然响应为忙。我想知道的是如何使背景工作者不忙。

EDIT 这些事件都在构造函数中添加,如下所示:

        SqlExpressDownloader = new BackgroundWorker();
        SqlExpressDownloader.DoWork += new DoWorkEventHandler(this.SqlExpressDownloader_DoWork);
        SqlExpressDownloader.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.SqlExpressDownloader_RunWorkerCompleted);

RunWorkerCompleteEventHandler看起来像这样:

    private void SqlExpressDownloader_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        if (e.Error != null)
        {
            Debug.WriteLine("The actions are complete.");
        }
        else
        {
            Debug.WriteLine("Error in completed work.");
        }
    }

但是,当我最后调试它时,它实际上并没有触发。

3 个答案:

答案 0 :(得分:3)

不是在循环中查询SqlExpressDownloader.IsBusy,而是尝试订阅RunWorkerCompleted的{​​{1}}事件,并将代码放在那里,只应在BackgroundWorker事件之后发生已经完成了。

您还可以访问DoWork,您可以检查RunWorkerCompletedEventArgs,以确保DoWork的{​​{1}}部分未发生任何错误。

BackgroundWorker

当我学习如何使用这些时,我发现Joe Albahari's tutorial很有帮助。

答案 1 :(得分:1)

您可以使用更优雅的异步/等待解决方案替换您的代码

private async Task SqlExpressDownloadAsync()
{
    string sSource = string.Format("{0}\\{1}", Paths.Settings_Common, "sqlexpr_x64_enu.exe");
    Debug.WriteLine(sSource);
    Debug.WriteLine("http://www.elexioamp.com/Install/redistributables/sql2008r2express/sqlexpr_x64_enu.exe");
    if (!System.IO.File.Exists(sSource))
    {
        WebClient oWebClient = new WebClient();
        oWebClient.DownloadProgressChanged += DownloadProgressChanged;
        oWebClient.DownloadDataCompleted += DownloadComplete;
        await oWebClient.DownloadFileTaskAsync(new System.Uri("http://www.elexioamp.com/Install/redistributables/sql2008r2express/sqlexpr_x64_enu.exe"), sSource);  
    }   
}

答案 2 :(得分:1)

我有类似的问题。 DownloadASync会解雇,但.IsBusy会一直保持正确。

这可能不会是一个常见的问题,只是想我分享我的决心。

我用过

MessageBox.Show(new Form() { TopMost = true }, "", "")

这就是原因。我也尝试过:

var t = new Form() { TopMost = true };
MessageBox.Show(t, "", "");
t.Dispose();

这引起了同样的问题。

我的代码有多个线程,我认为其中一个必须卡住,或者MessageBox(新的Form(){TopMost = true;})调用创建了一个卡住的线程。

我删除该部分后,例如

MessageBox.Show("", "");

一切都按预期工作了。

所以也许你正在某个地方创建另一个导致你的问题的线程。