转发BackgroundWorker的最小值和最大值以正确使用该函数

问题描述 投票:0回答:1

我一直在努力寻找一种解决方案,以解决如何将BackgroundWorker正确地集成到我的Feature中,并能够正确显示流程开发,流程停止,报告。

在我的问题中,我将尽最大努力拆分几乎所有代码,以便您可以更轻松地为我提供帮助,并引起您的注意,以便我可以正确地包含最小值(tb_min_Nr)而不是MinProgess = 0,如下所示以及最大值(tb_max_nr)而不是MaxProgress = 100。

这是我的应用程序的外观:enter image description here

这是我的代码

Public Class FormMain
    Public MasterMandantConnectionString As String
    Private fileWorker As BackgroundWorker(Of String(), String, List(Of FileData))
    Private files As String()

    Public Sub New()
        ' This call is required by the Windows Form Designer.
        InitializeComponent()
        fileWorker = New BackgroundWorker(Of String(), String, List(Of FileData))
        AddHandler fileWorker.DoWork, AddressOf fileWorker_DoWorkHandler
        AddHandler fileWorker.ProgressChanged, AddressOf fileWorker_ProgressChangedHandler
        AddHandler fileWorker.RunWorkerCompleted, AddressOf fileWorker_RunWorkerCompletedHandler
    End Sub

    Public Sub fileWorker_DoWorkHandler(ByVal sender As Object, ByVal e As DoWorkEventArgs(Of String(), List(Of FileData)))
        Dim progress As Integer = 0
        e.Result = New List(Of FileData)(e.Argument.Length)
        For Each file As String In e.Argument
            If fileWorker.CancellationPending Then
                e.Cancel = True
                Return
            End If
            fileWorker.ReportProgress(progress, file)
            Thread.Sleep(50)
            MasterMandantConnectionString = "Data Source=sql.com;Initial Catalog=Master;User ID=sa"
            For Mob_Nr = tb_Min_Nr.Value To tb_Max_Nr.Value

                Cdrs = Put_CDRs_To_FakturaPos(MasterMandantConnectionString:=MasterMandantConnectionString,
                                   Startdate:=dtp_Start.Value,
                                   EndDate:=dtp_End.Value,
                                   Mob_Nr:=Mob_Nr)

                For Each cdr In Cdrs
                    e.Result.Add(New FileData(cdr))
                Next
            Next

            progress += 2
        Next
        fileWorker.ReportProgress(progress, String.Empty)
    End Sub

    Public Sub fileWorker_ProgressChangedHandler _
        (ByVal sender As Object, ByVal e As ProgressChangedEventArgs(Of String))
        labelProgress.Text = e.UserState
        progressBar.Value = e.ProgressPercentage
    End Sub

    Public Sub fileWorker_RunWorkerCompletedHandler(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs(Of List(Of FileData)))
        If e.Cancelled Then
            labelProgress.Text = "Cancelled"
            progressBar.Value = 0
        Else
            labelProgress.Text = "Done!"
        End If
        listBox.DataSource = e.Result
        listBox.Enabled = True
        buttonStart.Enabled = True
        buttonCancel.Enabled = False
        progressBar.Enabled = False
        AcceptButton = buttonStart
    End Sub
    Dim Cdrs As List(Of String)


    Private Sub buttonStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles buttonStart.Click
        buttonCancel.Enabled = True
        AcceptButton = buttonCancel
        buttonStart.Enabled = False
        listBox.DataSource = Nothing
        listBox.Enabled = False
        files = Enumerable.Range(tb_Min_Nr.Value, tb_Max_Nr.Value).Select(Function(x) x.ToString).ToArray()
        fileWorker.RunWorkerAsync(files) 'my assumption is that in this part I am wrong, here I should pass min and max in order for the process to go from the minimum entered value to the maximum, it takes the current array list with me, and executes the process incorrectly.
    End Sub

    Private Sub buttonCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles buttonCancel.Click
        fileWorker.CancelAsync()
    End Sub

End Class


Public Class BackgroundWorker(Of TArgument, TProgress, TResult)

    Public Const MinProgress As Int32 = 0
    Public Const MaxProgress As Int32 = 100

    Public Event DoWork As EventHandler(Of DoWorkEventArgs(Of TArgument, TResult))
    Public Event ProgressChanged As EventHandler(Of ProgressChangedEventArgs(Of TProgress))
    Public Event RunWorkerCompleted As EventHandler(Of RunWorkerCompletedEventArgs(Of TResult))


    Private asyncOperation As AsyncOperation = Nothing
    Private ReadOnly threadStart As BasicDelegate
    Private ReadOnly operationCompleted As SendOrPostCallback
    Private ReadOnly progressReporterDelegate As SendOrPostCallback

    Private _CancellationPending As Boolean
    Private _IsBusy As Boolean
    Private _WorkerReportsProgress As Boolean
    Private _WorkerSupportsCancellation As Boolean

    Public Sub New()
        threadStart = AddressOf WorkerThreadStart
        operationCompleted = AddressOf AsyncOperationCompleted
        progressReporterDelegate = AddressOf ProgressReporter
        WorkerReportsProgress = True
        WorkerSupportsCancellation = True
    End Sub

    Public Property CancellationPending() As Boolean
        Get
            Return _CancellationPending
        End Get
        Private Set(ByVal value As Boolean)
            _CancellationPending = value
        End Set
    End Property

    Public Property IsBusy() As Boolean
        Get
            Return _IsBusy
        End Get
        Private Set(ByVal value As Boolean)
            _IsBusy = value
        End Set
    End Property

    Public Property WorkerReportsProgress() As Boolean
        Get
            Return _WorkerReportsProgress
        End Get
        Set(ByVal value As Boolean)
            _WorkerReportsProgress = value
        End Set
    End Property

    Public Property WorkerSupportsCancellation() As Boolean
        Get
            Return _WorkerSupportsCancellation
        End Get
        Set(ByVal value As Boolean)
            _WorkerSupportsCancellation = value
        End Set
    End Property

    Private Sub AsyncOperationCompleted(ByVal state As Object)
        IsBusy = False
        CancellationPending = False
        OnRunWorkerCompleted(CType(state, RunWorkerCompletedEventArgs(Of TResult)))
    End Sub

    Public Function CancelAsync() As Boolean
        If Not WorkerSupportsCancellation Then
            Return False
        End If
        CancellationPending = True
        Return True
    End Function

    Protected Overridable Sub OnDoWork(ByVal e As DoWorkEventArgs(Of TArgument, TResult))
        RaiseEvent DoWork(Me, e)
    End Sub

    Protected Overridable Sub OnProgressChanged(ByVal e As ProgressChangedEventArgs(Of TProgress))
        RaiseEvent ProgressChanged(Me, e)
    End Sub

    Protected Overridable Sub OnRunWorkerCompleted(ByVal e As RunWorkerCompletedEventArgs(Of TResult))
        RaiseEvent RunWorkerCompleted(Me, e)
    End Sub

    Private Sub ProgressReporter(ByVal state As Object)
        OnProgressChanged(CType(state, ProgressChangedEventArgs(Of TProgress)))
    End Sub

    Public Function ReportProgress(ByVal percentProgress As Int32) As Boolean
        Return ReportProgress(percentProgress, CType(Nothing, TProgress))
    End Function

    Public Function ReportProgress(ByVal percentProgress As Int32, ByVal userState As TProgress) As Boolean
        If Not WorkerReportsProgress Then
            Return False
        End If
        If percentProgress < MinProgress Then
            percentProgress = MinProgress
        ElseIf percentProgress > MaxProgress Then
            percentProgress = MaxProgress
        End If
        Dim args As ProgressChangedEventArgs(Of TProgress) =
            New ProgressChangedEventArgs(Of TProgress)(percentProgress, userState)
        If Not asyncOperation Is Nothing Then
            asyncOperation.Post(progressReporterDelegate, args)
        Else
            progressReporterDelegate(args)
        End If
        Return True
    End Function

    Public Function RunWorkerAsync() As Boolean
        Return RunWorkerAsync(CType(Nothing, TArgument))
    End Function

    Public Function RunWorkerAsync(ByVal argument As TArgument) As Boolean
        If IsBusy Then
            Return False
        End If
        IsBusy = True
        CancellationPending = False
        asyncOperation = AsyncOperationManager.CreateOperation(argument)
        threadStart.BeginInvoke(Nothing, Nothing)
        Return True
    End Function

    Private Sub WorkerThreadStart()
        Dim workerResult As TResult = CType(Nothing, TResult)
        Dim err As Exception = Nothing
        Dim cancelled As Boolean = False
        Try
            Dim doWorkArgs As DoWorkEventArgs(Of TArgument, TResult) =
                New DoWorkEventArgs(Of TArgument, TResult)(CType(asyncOperation.UserSuppliedState, TArgument))
            OnDoWork(doWorkArgs)
            If doWorkArgs.Cancel Then
                cancelled = True
            Else
                workerResult = doWorkArgs.Result
            End If
        Catch exception As Exception
            err = exception
        End Try
        Dim e As RunWorkerCompletedEventArgs(Of TResult) = New RunWorkerCompletedEventArgs(Of TResult)(workerResult, err, cancelled)
        asyncOperation.PostOperationCompleted(operationCompleted, e)
    End Sub

End Class

我的问题是,我可以在backgroundorker类中转发MinProgres和MaxpPogress值吗?

vb.net backgroundworker
1个回答
0
投票

如果您有一些要包含在进度报告中的信息,则可以为其创建一个类:

Private Class ProgressReportData
    Property CurrentMin As Integer
    Property CurrentMax As Integer
    ' Other properties as needed.
End Class

然后像这样使用它来填充e.UserState对象:

e.UserState

并处理事件:

Dim progReport As New ProgressReportData With {.CurrentMin = x, .CurrentMax = y}
worker.ReportProgress(percentSoFar, progReport)
© www.soinside.com 2019 - 2024. All rights reserved.