0

在我的应用程序启动期间,我正在进行长时间的数据库升级。在此开始之前,我展示了一个带有进度条的表单,以便用户知道正在发生某些事情并且他应该等待。

为了不阻止重绘进度条,我在后台工作人员中进行数据库升级。

代码如下所示:

            frmMain_Load(...)

            Dim wait As New frmWait
            wait.Show()

            Dim bw As New frmBWRebuildUserData
            bw.Start()
            Do While Not bw.Done
                System.Threading.Thread.Sleep(100)
            Loop

            'Okay, db update was done, now continue and show the main app window

我的 frmBWRebuildUserData 看起来像这样:

Public Class frmBWRebuildUserData

Private m_bDone As Boolean

Public ReadOnly Property Done() As Boolean

    Get
        Return m_bDone
    End Get

End Property

Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork

    modAppDB.RebuildUserDB()

End Sub
Public Sub Start()

    Me.BackgroundWorker1.RunWorkerAsync()

End Sub

Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted

    m_bDone = True

End Sub
End Class

但是 60 秒后,VB.NET 告诉我自 60 秒以来没有消息(我猜你知道这个错误)。

但是由于后台工作人员是为此目的而设计的,所以我认为我在这里做错了什么,但我不知道是什么。

另外,我的进度条没有重绘。

有人可以帮忙吗?非常感谢你!

4

2 回答 2

1

有几件事。

后台工作程序中没有内置的 60 秒超时。所以它应该在你的代码中。

为什么要使用 backgroundWorker,然后在代码中引入睡眠周期?应该使用后台工作程序来使用户界面免于等待长时间操作的结束。

当被要求向用户界面元素报告其进度时,后台工作人员需要这样的东西(抱歉是 C#,但我认为你可以明白这一点)

 backgroundworker.ProgressChanged += backgroundworker_ProgressChanged;
 backgroundworker.WorkerReportsProgress = true;

在这种情况下,您modAppDB.RebuildUserDB()需要致电

 backgroundworker.ReportProgress(percentComplete);

对于您想要与进度条进行通信的每个步骤,当然,您需要在显示进度条的表单中拦截由 ReportProgress 调用触发的事件

private void backgroundworker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressBar.Value = (e.ProgressPercentage.ToString() + "%");
}
于 2012-12-21T10:19:14.990 回答
1

Backgroundworker 主要适用于在 DoWork 中有循环的任务,它允许您在循环中执行一些 UI 反馈。如果你的 DoWork 只是调用另一个命令,它会等待这个命令完成并且在这段时间内不做任何事情。除此之外,使用 BGW 仍然允许主线程处理其消息而不会被阻塞,所以我认为在这里使用它仍然是完全正确的。
除此之外,您backgroundworker1的未声明,正如史蒂夫指出的那样,您的 Start()-Method 至少需要这第一行:
Addhandler Backgroundworker1.DoWork, AddressOf BackgroundWorker1_DoWork. 这会在调用时触发该函数RunworkerAsync
有关线程通信的基本示例(以及与之相关的基本问题),请查看以下问题和答案:
进度条和代码位置的多线程(vb.net)?
我也不知道60秒的问题。

于 2012-12-21T11:38:11.477 回答