vb.net 进度条和后台工作者
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27565851/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Progress Bar and Background Worker
提问by Neophile
I have a progress bar and backgroundworker in VB.Net that I would want to work in a different form as given below:
我在 VB.Net 中有一个进度条和 backgroundworker,我想以不同的形式工作,如下所示:
Form1()
{
MaxRows = 10
for i = 0 to MaxRows then
// Update my value on the progressbar
....
next
}
ProgressBarForm
进度条表格
Private Sub ProgressBarForm_Shown(sender As Object, e As EventArgs) Handles Me.Shown
TransferProgressBar.Visible = True
ProgressBarBackgroundWorker.RunWorkerAsync()
End Sub
Private Sub ProgressBarBackgroundWorker_DoWork(sender As Object, e As ComponentModel.DoWorkEventArgs) Handles ProgressBarBackgroundWorker.DoWork
For i = 0 To TransferProgressBar.Maximum
'Dim Percentage As Integer = Math.Round(((i / (TransferProgressBar.Maximum - TransferProgressBar.Minimum)) * 100))
ProgressBarBackgroundWorker.ReportProgress(i / 100)
Next
End Sub
Private Sub ProgressBarBackgroundWorker_ProgressChanged(sender As Object, e As ComponentModel.ProgressChangedEventArgs) Handles ProgressBarBackgroundWorker.ProgressChanged
TransferProgressBar.Value = e.ProgressPercentage
PercentageLabel.Text = "Processing....." & TransferProgressBar.Value.ToString() & "%"
End Sub
Private Sub ProgressBarBackgroundWorker_RunWorkerCompleted(sender As Object, e As ComponentModel.RunWorkerCompletedEventArgs) Handles ProgressBarBackgroundWorker.RunWorkerCompleted
MsgBox("Task Completed!")
Me.Close()
End Sub
How can I update my progressbar value using the backgroundworker from another form/Sub? Kindly let me know. I'm getting a bit confused here.
如何使用来自另一个表单/Sub 的后台工作程序更新我的进度条值?请让我知道。我在这里有点困惑。
回答by ??ssa P?ngj?rdenlarp
You seem to have it back to front. Rather than the BackgroundWorkerhandling the ProgressBarupdates, use the BGW to do the time consuming work. Then at intervals you can provide updates for the ProgressBar/Form using the built-in ReportProgressmethod.
你似乎把它倒过来了。不是BackgroundWorker处理ProgressBar更新,而是使用 BGW 来完成耗时的工作。然后,您可以每隔一段时间使用内置ReportProgress方法为 ProgressBar/Form 提供更新。
Normally, you cannot (directly) access UI controls, like a ProgressBar, from a thread other than the one it was created on (ie the UI thread). The ReportProgressevent is raised on the original/UI thread to make basic progress reporting easy.
通常,您不能(直接)ProgressBar从创建它的线程以外的线程(即 UI 线程)访问 UI 控件,例如。该ReportProgress事件是在原始/UI 线程上引发的,以使基本的进度报告变得容易。
However, it is pretty much limited to only that. To do more, for instance post results of the long process to a ListBox, you would use a Delegate to update the control on the other/UI thread.
然而,它几乎仅限于此。要执行更多操作,例如将长过程的结果发布到 a ListBox,您可以使用 Delegate 来更新其他/UI 线程上的控件。
The Form with the long running task
带有长时间运行任务的表单
Private WithEvents bgw As New BackgroundWorker
Private frmProg As ProgForm ' progress bar form
' start up
Private Sub Button1_Click(sender ...etc
' set up
bgw.WorkerReportsProgress = True
bgw.WorkerSupportsCancellation = True
If frmProg Is Nothing Then ' make sure progress form is instanced
ProgForm = New frmProg
End If
If bgw.IsBusy = False Then
frmProg.Show()
bgw.RunWorkerAsync(10) ' do some important work x10
End If
End Sub
' the job that will take a while
Private Sub bgw_DoWork(sender As Object, e As DoWorkEventArgs)
Handles bgw.DoWork
' ToDo: with multiple workers use sender, not 'bgw'
' get the amount of work to do
Dim numToDo As Integer = CInt(e.Argument)
' important, time consuming work done here
For n As Integer = 1 To numToDo
' do the "work"
System.Threading.Thread.Sleep(100)
' post a notice, passing the percentage (raises the ProgressChanged event)
bgw.ReportProgress(Convert.ToInt32((n / numToDo) * 100)
Next
End Sub
' event raised from DoWork via ReportProgress
Private Sub bgw_ProgressChanged(sender As Object, e As ProgressChangedEventArgs)
Handles bgw.ProgressChanged
' method added on the Progress form to
' receive percentage and update the meter:
frmProg.UpdateProgress(e.ProgressPercentage)
' if the progress bar was on the same form,
' update it directly:
'MyProgBar.Value = MyProgBar.Maximum
'MyProgBar.Value = pct
End Sub
' optional event raised when the long running task is complete
Private Sub bgw_RunWorkerCompleted(sender As Object,
e As RunWorkerCompletedEventArgs) Handles bgw.RunWorkerCompleted
' when all done, report that too
MessageBox.Show("Work Complete!")
End Sub
Note that normally using Thread.Sleepfreezes the UI. That doesnt happen here because it is the BackgroundWorkernot the UI thread which is put to sleep.
请注意,通常使用会Thread.Sleep冻结 UI。这不会发生在这里,因为它BackgroundWorker不是进入睡眠状态的 UI 线程。
The Form with the progress bar:
带进度条的表单:
Public Sub UpdateProgress(pct As Integer)
' ToDo: Add error checking
progress.Value = progress.Maximum
progress.Value = pct
End Sub

