VB.net - 使用BackgroundWorker的Progressbar

时间:2016-09-08 14:08:20

标签: .net vb.net progress-bar backgroundworker

我正在尝试使用BackgroundWorker实现进度条。

但是进度条会在一秒钟之后隐藏起来并且它不会保持在最顶层。不确定原因。

以下是我的表格代码:

Private Sub btnProgressBarPOC_Click(sender As Object, e As EventArgs) Handles btnProgressBarPOC.Click
    BackgroundWorker = New BackgroundWorker()
    BackgroundWorker.WorkerReportsProgress = True
    autoResetEvent = New AutoResetEvent(False)
    ProgressBar = New frmProgressBar(BackgroundWorker)
    ProgressBar.ShowDialog()

    autoResetEvent.WaitOne()
    MsgBox("Main Done", vbInformation)
End Sub

Sub Processing() Handles BackgroundWorker.DoWork
    BackgroundWorker.ReportProgress(33)
    Threading.Thread.Sleep(5000)

    BackgroundWorker.ReportProgress(66)
    Threading.Thread.Sleep(5000)

    BackgroundWorker.ReportProgress(100)

    MsgBox("Background Done", vbInformation)
    AutoResetEvent.Set()
End Sub

以下是我的代码,其中包含进度条:

Imports System.ComponentModel

Public Class frmProgressBar

    Private WithEvents _BGW As System.ComponentModel.BackgroundWorker
    Private _TaskInProgress As String

    Public WriteOnly Property TaskInProgress()
        Set(value)
            _TaskInProgress = value
            _BGW.ReportProgress(1)
        End Set
    End Property

    Public Sub New(ByVal BGW As System.ComponentModel.BackgroundWorker)
        _BGW = BGW
        InitializeComponent()
    End Sub

    Private Sub frmProgress_Shown(sender As Object, e As System.EventArgs) Handles Me.Shown
        If Not IsNothing(_BGW) Then
            _BGW.RunWorkerAsync()
        End If
    End Sub

    Private Sub _BGW_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles _BGW.ProgressChanged
        progressBar.Value = e.ProgressPercentage

        If Me.Text <> _TaskInProgress Then
            Me.Text = _TaskInProgress
        End If
    End Sub

    Private Sub _BGW_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles _BGW.RunWorkerCompleted
        Me.Close()
        _TaskInProgress = ""
    End Sub

    'Private Sub _BGW_DoWork(sender As Object, e As DoWorkEventArgs) Handles _BGW.DoWork
    '    Do While True
    '        ' Has the background worker be told to stop?
    '        If _BGW.CancellationPending Then
    '            ' Set Cancel to True
    '            e.Cancel = True
    '            Exit Do
    '        End If
    '        System.Threading.Thread.Sleep(2000) ' Sleep for 1 Second
    '    Loop
    'End Sub
End Class
  

我在这里上传了我的项目:   https://drive.google.com/file/d/0B7gzonuQsNbvaDZvR3ltSl9WNTg/view?usp=sharing

2 个答案:

答案 0 :(得分:0)

您不需要AutoReset事件,因为您可以处理RunWorkerCompleted事件。目前您正在阻止UI线程。

从RunWorkerAsync中删除msgbox,这应该在你的ui线程上处理。

我怀疑它是导致RunWorkerAsync退出的异常,因此请检查RunWorkerCompleted事件中的错误代码。这可能是由您的TaskInProgress属性引起的,该属性通过环形交叉方式与文本框进行交互,尽管它位于后台线程上。

而是更新TaskInProgress文本框,将其作为ReportProgress的额外参数发送,并从进度框中取回。

BackgroundWorker.ReportProgress(33, "Hello")

Private Sub _BGW_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles _BGW.ProgressChanged
    Me.Text = CStr(e.UserState)
     ....

答案 1 :(得分:0)

以下是经过纠正的代码:

Public Class frmMisc
    Private WithEvents BackgroundWorker As BackgroundWorker, ProgressBar As frmProgressBar

    Private Sub btnProgressBarPOC_Click(sender As Object, e As EventArgs) Handles btnProgressBarPOC.Click
        Call RunProcessing()

        MsgBox("Main Done", vbInformation)
    End Sub

    Sub RunProcessing()
        BackgroundWorker = New BackgroundWorker()
        BackgroundWorker.WorkerReportsProgress = True
        ProgressBar = New frmProgressBar(BackgroundWorker)
        ProgressBar.ShowDialog()
    End Sub

    Sub Processing() Handles BackgroundWorker.DoWork
        BackgroundWorker.ReportProgress(33, "Step-1")
        Threading.Thread.Sleep(3000)

        BackgroundWorker.ReportProgress(66, "Step-2")
        Threading.Thread.Sleep(2000)

        BackgroundWorker.ReportProgress(100, "Step-3")
    End Sub
End Class

Public Class frmProgressBar

    Private WithEvents _BGW As System.ComponentModel.BackgroundWorker
    Private _TaskInProgress As String

    Public Sub New(ByVal BGW As System.ComponentModel.BackgroundWorker)
        _BGW = BGW
        InitializeComponent()
    End Sub

    Private Sub frmProgress_Shown(sender As Object, e As System.EventArgs) Handles Me.Shown
        If Not IsNothing(_BGW) Then
            _BGW.RunWorkerAsync()
        End If
    End Sub

    Private Sub _BGW_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles _BGW.ProgressChanged
        progressBar.Value = e.ProgressPercentage

        Me.Text = e.UserState
    End Sub

    Private Sub _BGW_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles _BGW.RunWorkerCompleted
        Me.Close()
        _TaskInProgress = ""
    End Sub
End Class
  

我在ProgressChanged之外做了Me.Text甚至是   造成这个问题。   感谢@Hans提供关于此的提示!