backgroundWorker 仅在取消时更新进度
backgroundWorker update progress only at cancellation
我想在表单 'dinamic label' 上显示它只写 'Loading' 而另一个线程正在工作。
标签应在此模式下更改:
L, Lo, Loa, Load, Loadi, Loadin, Loading, oading, ading, ding, ing, ng, g
我编写了代码,但是 'BackGroundWorker_ProgressChanged 事件仅在 BackGroundWorker.CancellationPending = True 时才被调用。
然后,发送所有更新。
这里是代码
Public Class Form1
Dim WithEvents bgw As New BackgroundWorker
Dim WithEvents I_MyClass As MyNewClass
Dim lLoading As New Label
Dim WithEvents T As New Timer
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
bgw.WorkerReportsProgress = True
bgw.WorkerSupportsCancellation = True
I_MyClass = New MyNewClass
AddHandler I_MyClass.Start, AddressOf StartLoading
AddHandler I_MyClass.Stop, AddressOf StopLoading
With lLoading
.Size = New Size(120, 25)
.Location = New Point(10, 10)
End With
Me.Controls.Add(lLoading)
T.Interval = 1000
AddHandler T.Tick, AddressOf T_Tick
T.Start()
End Sub
Private Sub T_Tick(sender As Object, e As EventArgs) Handles T.Tick
T.Stop()
I_MyClass.StartLoading()
End Sub
Public Sub StartLoading()
If bgw.IsBusy Then Exit Sub
bgw.RunWorkerAsync()
End Sub
Public Sub StopLoading()
bgw.CancelAsync()
End Sub
Private Sub bgw_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles bgw.DoWork
Dim worker As System.ComponentModel.BackgroundWorker = CType(sender, System.ComponentModel.BackgroundWorker)
Dim i As Integer = 1
Dim loadingString As String = "Loading......."
Do
If (worker.CancellationPending = True) Then
e.Cancel = True
Exit Do
Else
Threading.Thread.Sleep(500)
worker.ReportProgress(i)
If i = loadingString.Count Then i = 1 Else i += 1
End If
Loop
End Sub
Private Sub bgw_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles bgw.ProgressChanged
Dim loadingString As String = "Loading......."
Dim i As Integer = e.ProgressPercentage
Dim l As Integer = lLoading.Text.Count
If l < i Then
lLoading.Text = loadingString.Substring(0, i)
Else
lLoading.Text = loadingString.Substring(i, l - i)
End If
End Sub
End Class
Public Class MyNewClass
Sub New()
End Sub
Public Event Start()
Public Event [Stop]()
Public Sub StartLoading()
RaiseEvent Start()
' simulate download
For a = 0 To 10
Threading.Thread.Sleep(1000)
Next a
RaiseEvent Stop()
End Sub
End Class
不明白为什么'BackGroundWorker_ProgressChanged事件不调用报告部分进度,而是在BackGroundWorker.CancellationPending = True时才调用几次。
P.S。也欢迎 c# 帮助。
Don't understand why the 'BackGroundWorker_ProgressChanged event it's not called reporting partial progress
因为您有一个计时器启动非常阻塞、非常不异步的 StartLoading 方法。
您似乎是从主线程调用此代码:
For a = 0 to 10
Threading.Thread.Sleep(1000)
Next a
因此您的应用将在 11 秒内完全聋哑。没有时间进行屏幕更新或进度事件,我们正忙于睡觉。
感谢 Bommelding,我注意到我忘记了在单独的线程中开始下载,因此 Bommelding 让我注意到,指令 'threading.thread.sleep() 正在停止标签更新
这里的代码更正了。
Imports System.ComponentModel
Public Class Form1
Dim WithEvents bgw As New BackgroundWorker
Dim WithEvents I_MyClass As MyNewClass
Dim lLoading As New Label
Dim WithEvents T As New Timer
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
bgw.WorkerReportsProgress = True
bgw.WorkerSupportsCancellation = True
I_MyClass = New MyNewClass
AddHandler I_MyClass.Start, AddressOf StartLoading
AddHandler I_MyClass.Stop, AddressOf StopLoading
With lLoading
.Size = New Size(120, 25)
.Location = New Point(10, 10)
.TextAlign = ContentAlignment.MiddleCenter
.Tag = "Loading"
For a = 0 To CStr(.Tag).Count - 1
.Text += " "
Next
End With
Me.Controls.Add(lLoading)
T.Interval = 1000
AddHandler T.Tick, AddressOf T_Tick
T.Start()
End Sub
Private Sub T_Tick(sender As Object, e As EventArgs) Handles T.Tick
T.Stop()
I_MyClass.StartLoading()
End Sub
Public Sub StartLoading()
If bgw.IsBusy Then Exit Sub
bgw.RunWorkerAsync(CStr(lLoading.Tag).Count - 1)
End Sub
Public Sub StopLoading()
bgw.CancelAsync()
End Sub
Private Sub bgw_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles bgw.DoWork
Dim worker As System.ComponentModel.BackgroundWorker = CType(sender, System.ComponentModel.BackgroundWorker)
Dim limit As Integer = CInt(e.Argument)
Dim i As Integer = 0
Do
If (worker.CancellationPending = True) Then
e.Cancel = True
Exit Do
Else
Threading.Thread.Sleep(100)
worker.ReportProgress(i)
If i = limit Then i = 0 Else i += 1
End If
Loop
i = Nothing
limit = Nothing
worker = Nothing
End Sub
Private Sub bgw_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles bgw.ProgressChanged
Dim loadingString As String = CStr(lLoading.Tag)
Dim i As Integer = e.ProgressPercentage
'Dim l As Integer = lLoading.Text.Count
If lLoading.Text(i) <> loadingString(i) Then
Mid(lLoading.Text, i + 1, 1) = loadingString(i)
Else
Mid(lLoading.Text, i + 1, 1) = " "
End If
i = Nothing
loadingString = Nothing
End Sub
Private Sub bgw_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles bgw.RunWorkerCompleted
For a = 0 To CStr(lLoading.Tag).Count - 1
lLoading.Text += " "
Next
End Sub
End Class
Public Class MyNewClass
Sub New()
bgwDoSameWork.WorkerReportsProgress = True
bgwDoSameWork.WorkerSupportsCancellation = True
End Sub
Public Event Start()
Public Event [Stop]()
Private WithEvents bgwDoSameWork As New BackgroundWorker
Public Sub StartLoading()
' simulate download
If bgwDoSameWork.IsBusy = False Then
RaiseEvent Start()
bgwDoSameWork.RunWorkerAsync()
End If
End Sub
Private Sub bgwDoSameWork_DoWork(sender As Object, e As DoWorkEventArgs) Handles bgwDoSameWork.DoWork
For a = 0 To 10
Threading.Thread.Sleep(1000)
Next a
End Sub
Private Sub bgwDoSameWork_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles bgwDoSameWork.RunWorkerCompleted
RaiseEvent Stop()
End Sub
End Class
我想在表单 'dinamic label' 上显示它只写 'Loading' 而另一个线程正在工作。 标签应在此模式下更改:
L, Lo, Loa, Load, Loadi, Loadin, Loading, oading, ading, ding, ing, ng, g
我编写了代码,但是 'BackGroundWorker_ProgressChanged 事件仅在 BackGroundWorker.CancellationPending = True 时才被调用。
然后,发送所有更新。
这里是代码
Public Class Form1
Dim WithEvents bgw As New BackgroundWorker
Dim WithEvents I_MyClass As MyNewClass
Dim lLoading As New Label
Dim WithEvents T As New Timer
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
bgw.WorkerReportsProgress = True
bgw.WorkerSupportsCancellation = True
I_MyClass = New MyNewClass
AddHandler I_MyClass.Start, AddressOf StartLoading
AddHandler I_MyClass.Stop, AddressOf StopLoading
With lLoading
.Size = New Size(120, 25)
.Location = New Point(10, 10)
End With
Me.Controls.Add(lLoading)
T.Interval = 1000
AddHandler T.Tick, AddressOf T_Tick
T.Start()
End Sub
Private Sub T_Tick(sender As Object, e As EventArgs) Handles T.Tick
T.Stop()
I_MyClass.StartLoading()
End Sub
Public Sub StartLoading()
If bgw.IsBusy Then Exit Sub
bgw.RunWorkerAsync()
End Sub
Public Sub StopLoading()
bgw.CancelAsync()
End Sub
Private Sub bgw_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles bgw.DoWork
Dim worker As System.ComponentModel.BackgroundWorker = CType(sender, System.ComponentModel.BackgroundWorker)
Dim i As Integer = 1
Dim loadingString As String = "Loading......."
Do
If (worker.CancellationPending = True) Then
e.Cancel = True
Exit Do
Else
Threading.Thread.Sleep(500)
worker.ReportProgress(i)
If i = loadingString.Count Then i = 1 Else i += 1
End If
Loop
End Sub
Private Sub bgw_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles bgw.ProgressChanged
Dim loadingString As String = "Loading......."
Dim i As Integer = e.ProgressPercentage
Dim l As Integer = lLoading.Text.Count
If l < i Then
lLoading.Text = loadingString.Substring(0, i)
Else
lLoading.Text = loadingString.Substring(i, l - i)
End If
End Sub
End Class
Public Class MyNewClass
Sub New()
End Sub
Public Event Start()
Public Event [Stop]()
Public Sub StartLoading()
RaiseEvent Start()
' simulate download
For a = 0 To 10
Threading.Thread.Sleep(1000)
Next a
RaiseEvent Stop()
End Sub
End Class
不明白为什么'BackGroundWorker_ProgressChanged事件不调用报告部分进度,而是在BackGroundWorker.CancellationPending = True时才调用几次。
P.S。也欢迎 c# 帮助。
Don't understand why the 'BackGroundWorker_ProgressChanged event it's not called reporting partial progress
因为您有一个计时器启动非常阻塞、非常不异步的 StartLoading 方法。
您似乎是从主线程调用此代码:
For a = 0 to 10
Threading.Thread.Sleep(1000)
Next a
因此您的应用将在 11 秒内完全聋哑。没有时间进行屏幕更新或进度事件,我们正忙于睡觉。
感谢 Bommelding,我注意到我忘记了在单独的线程中开始下载,因此 Bommelding 让我注意到,指令 'threading.thread.sleep() 正在停止标签更新 这里的代码更正了。
Imports System.ComponentModel
Public Class Form1
Dim WithEvents bgw As New BackgroundWorker
Dim WithEvents I_MyClass As MyNewClass
Dim lLoading As New Label
Dim WithEvents T As New Timer
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
bgw.WorkerReportsProgress = True
bgw.WorkerSupportsCancellation = True
I_MyClass = New MyNewClass
AddHandler I_MyClass.Start, AddressOf StartLoading
AddHandler I_MyClass.Stop, AddressOf StopLoading
With lLoading
.Size = New Size(120, 25)
.Location = New Point(10, 10)
.TextAlign = ContentAlignment.MiddleCenter
.Tag = "Loading"
For a = 0 To CStr(.Tag).Count - 1
.Text += " "
Next
End With
Me.Controls.Add(lLoading)
T.Interval = 1000
AddHandler T.Tick, AddressOf T_Tick
T.Start()
End Sub
Private Sub T_Tick(sender As Object, e As EventArgs) Handles T.Tick
T.Stop()
I_MyClass.StartLoading()
End Sub
Public Sub StartLoading()
If bgw.IsBusy Then Exit Sub
bgw.RunWorkerAsync(CStr(lLoading.Tag).Count - 1)
End Sub
Public Sub StopLoading()
bgw.CancelAsync()
End Sub
Private Sub bgw_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles bgw.DoWork
Dim worker As System.ComponentModel.BackgroundWorker = CType(sender, System.ComponentModel.BackgroundWorker)
Dim limit As Integer = CInt(e.Argument)
Dim i As Integer = 0
Do
If (worker.CancellationPending = True) Then
e.Cancel = True
Exit Do
Else
Threading.Thread.Sleep(100)
worker.ReportProgress(i)
If i = limit Then i = 0 Else i += 1
End If
Loop
i = Nothing
limit = Nothing
worker = Nothing
End Sub
Private Sub bgw_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles bgw.ProgressChanged
Dim loadingString As String = CStr(lLoading.Tag)
Dim i As Integer = e.ProgressPercentage
'Dim l As Integer = lLoading.Text.Count
If lLoading.Text(i) <> loadingString(i) Then
Mid(lLoading.Text, i + 1, 1) = loadingString(i)
Else
Mid(lLoading.Text, i + 1, 1) = " "
End If
i = Nothing
loadingString = Nothing
End Sub
Private Sub bgw_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles bgw.RunWorkerCompleted
For a = 0 To CStr(lLoading.Tag).Count - 1
lLoading.Text += " "
Next
End Sub
End Class
Public Class MyNewClass
Sub New()
bgwDoSameWork.WorkerReportsProgress = True
bgwDoSameWork.WorkerSupportsCancellation = True
End Sub
Public Event Start()
Public Event [Stop]()
Private WithEvents bgwDoSameWork As New BackgroundWorker
Public Sub StartLoading()
' simulate download
If bgwDoSameWork.IsBusy = False Then
RaiseEvent Start()
bgwDoSameWork.RunWorkerAsync()
End If
End Sub
Private Sub bgwDoSameWork_DoWork(sender As Object, e As DoWorkEventArgs) Handles bgwDoSameWork.DoWork
For a = 0 To 10
Threading.Thread.Sleep(1000)
Next a
End Sub
Private Sub bgwDoSameWork_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles bgwDoSameWork.RunWorkerCompleted
RaiseEvent Stop()
End Sub
End Class