gpt4 book ai didi

vb.net 更新进度条多线程

转载 作者:行者123 更新时间:2023-12-03 13:19:43 35 4
gpt4 key购买 nike

长期读者,第一次海报。通常我能够找到答案并使其发挥作用。这次不是......我在 VS2013 中使用 VB.NET。我正在尝试使用在辅助线程中完成的工作来更新进度条。容易吧?不,我不得不让它变得更复杂。进度条 ( ToolStripProgressBar1 ) 位于项目的 MDI 主窗体 ( frmMain ) 上。辅助形式 ( frmShipping ) 有一个按钮,用于启动第二个线程以在类 ( cApex ) 中进行一些 COMM 端口通信。我可以在 上获取更新进度条frmMain 从主 UI 线程( frmShipping 按钮)。

这是 上按钮的代码frmShiping 和多线程过程:

 Private Sub btnreadScanner_Click(sender As Object, e As EventArgs) Handles btnreadScanner.Click

Dim thrReadScanner As New System.Threading.Thread(AddressOf ReadScanner)
thrReadScanner.IsBackground = True
thrReadScanner.Start()

End Sub

Private Sub ReadScanner()

Dim strRowCount As String
ShipmentMsg(2)
strRowCount = objShipping.RecordsExisit.ToString()

Try
objApex.ImmediateMode()
If objApex.FileDownload = False Then
Throw New Exception(Err.Description)
End If
Catch ex As Exception
ShipmentMsg(1)
MessageBox.Show("No Data downloaded from Scanner. Try Again. Error#: " & Err.Number & " : " & Err.Description)
Exit Sub
End Try

RecordCount()
DataGridUpdate()
btnProcessShipment.Enabled = True
ShipmentMsg(5)
ScanErrors()

End Sub

这一切都很好。正如预期的那样。调用 objApex.FileDownload 在类里面 顶点 是更新进度条的地方(实际上是在另一个从 FileDownload 调用的函数中)。所以这里是那里的代码。
Try
GetHeaderRecord()
If Count <> 0 Then intTicks = Math.Round((100 / Count), 1)
For intcount As Integer = 1 To Count
Dim intLength As Integer = Length
Do While intLength > 0
literal = Chr(_serialPort.ReadChar.ToString)
If literal = ">" Then Exit Do
strRecord = strRecord & literal
intLength = intLength - 1
Loop
REF = strRecord.Substring(0, 16).TrimEnd
SKID = strRecord.Substring(16, 16).TrimEnd
REEL_BC = strRecord.Substring(32, 15).TrimEnd
ScanDate = strRecord.Substring(47, 8).TrimEnd
ScanDate = DateTime.ParseExact(ScanDate, "yyyyMMdd", Nothing).ToString("MM/dd/yyyy")
ScanTime = strRecord.Substring(55, 6).TrimEnd
ScanTime = DateTime.ParseExact(ScanTime, "HHmmss", Nothing).ToString("HH:mm:ss")
strRecordTotal = strRecordTotal & strRecord & CRLF
Dim strSQL As String
strSQL = "INSERT INTO tblScanData (PONo,Barcode,SkidNo,ScanDate,ScanTime) " & _
"VALUES (" & _
Chr(39) & REF & Chr(39) & _
"," & Chr(39) & REEL_BC & Chr(39) & _
"," & Chr(39) & SKID & Chr(39) & _
"," & Chr(39) & ScanDate & Chr(39) & _
"," & Chr(39) & ScanTime & Chr(39) & ")"
objData.Executecommand(strSQL)
strRecord = ""
Next

最后这就是我调用进度条更新的方式。
Dim f As frmMain = frmMain
System.Threading.Thread.Sleep(100)
DirectCast(f, frmMain).ToolStripProgressBar1.PerformStep()

我真的需要将 PerformStep 放在 For 循环中。每次循环都会步进进度条所需的步骤百分比,以使进度条相当准确(由循环前的数学代码完成)。我还在 上设置了进度条控件的属性。 frmMain .那么,我疯了,还是有办法做到这一点?我尝试使用委托(delegate); Me.Invoke(新 MethodInvoker(AddressOf pbStep)) 使代码跨线程安全。我没有收到有关跨线程调用的错误,但进度条也没有更新。抱歉,这很长,但我迷路了,我的多动症不会让我放弃这个想法。

按要求编辑:
 Public Sub pbStep()

Dim f As frmMain = frmMain
If Me.InvokeRequired Then
Me.Invoke(New MethodInvoker(AddressOf pbStep))
Else
DirectCast(f, frmMain).ToolStripProgressBar1.PerformStep()
System.Threading.Thread.Sleep(100)
End If

End Sub

最佳答案

两种回答都帮助我找到了我需要的正确答案。 James 提供的代码是一个很好的起点,Hans 有几篇文章解释了 BackgroundWorker。我想分享我想出的“答案”。我并不是说这是最好的方法,我确信我违反了一些常见的逻辑规则。此外,许多代码来自 MSDN 示例和 James 的代码。

让我们从我调用 bgw 的表单开始,frmShipping。我添加了这段代码:

Dim WithEvents bgw1 As New System.ComponentModel.BackgroundWorker

Private Sub bgw1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) _
Handles bgw1.RunWorkerCompleted

If e.Error IsNot Nothing Then
MessageBox.Show("Error: " & e.Error.Message)
ElseIf e.Cancelled Then
MessageBox.Show("Process Canceled.")
Else
MessageBox.Show("Finished Process.")
End If

End Sub

Private Sub bgw1_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) _
Handles bgw1.ProgressChanged
DirectCast(Me.MdiParent, frmMain).ToolStripProgressBar1.Maximum = 1960
DirectCast(Me.MdiParent, frmMain).ToolStripProgressBar1.Step = 2

Dim state As cApex.CurrentState =
CType(e.UserState, cApex.CurrentState)
DirectCast(Me.MdiParent, frmMain).txtCount.Text = state.LinesCounted.ToString
DirectCast(Me.MdiParent, frmMain).txtPercent.Text = e.ProgressPercentage.ToString
DirectCast(Me.MdiParent, frmMain).ToolStripProgressBar1.PerformStep()

End Sub
Private Sub bgw1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) _
Handles bgw1.DoWork

Dim worker As System.ComponentModel.BackgroundWorker
worker = CType(sender, System.ComponentModel.BackgroundWorker)

Dim objApex As cApex = CType(e.Argument, cApex)
objApex.CountLines(worker, e)

End Sub

Sub StartThread()

Me.txtCount.Text = "0"
Dim objApex As New cApex
bgw1.WorkerReportsProgress = True
bgw1.RunWorkerAsync(objApex)

End Sub

接下来,我在我的 cApex 类中添加了以下代码。
Public Class CurrentState
Public LinesCounted
End Class

Private LinesCounted As Integer = 0


Public Sub CountLines(ByVal worker As System.ComponentModel.BackgroundWorker, _
ByVal e As System.ComponentModel.DoWorkEventArgs)
Dim state As New CurrentState
Dim line = ""
Dim elaspedTime = 20
Dim lastReportDateTime = Now
Dim lineCount = File.ReadAllLines(My.Settings.strGenFilePath).Length
Dim percent = Math.Round(100 / lineCount, 2)
Dim totaldone As Double = 2

Using myStream As New StreamReader(My.Settings.strGenFilePath)

Do While Not myStream.EndOfStream
If worker.CancellationPending Then
e.Cancel = True
Exit Do
Else
line = myStream.ReadLine
LinesCounted += 1
totaldone += percent

If Now > lastReportDateTime.AddMilliseconds(elaspedTime) Then
state.LinesCounted = LinesCounted
worker.ReportProgress(totaldone, state)
lastReportDateTime = Now
End If
System.Threading.Thread.Sleep(2)
End If
Loop

state.LinesCounted = LinesCounted
worker.ReportProgress(totaldone, state)

End Using

End Sub

我还在我的主窗体中添加了几个文本框,以显示正在读取的文件的当前行数以及以 100 的百分比表示的总体进度。然后在我的按钮的 Click 事件中,我只需调用 StartThread() .它不是 100% 准确的,但它足够接近,可以让用户很好地了解流程的位置。我还有一些工作要做,以将其添加到“ReadScanner”功能,我最初想在其中使用进度条。但这个功能是我在扫描仪上执行的两个功能中较长的一个,通过一个 COMM 端口编写了近 2,000 行代码。我对结果很满意。

谢谢各位帮忙!

附言我现在还添加了变量来设置 pbar.Maximumpbar.step因为如果扫描仪文件更改,这些可能会更改。

关于vb.net 更新进度条多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26813798/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com