【发布时间】:2012-09-21 15:19:32
【问题描述】:
我无法从不同的线程更新进度条。 我确实让它以最简单的方式运行,但是清理代码让我卡住了。
我的测试代码看起来像网络上所有与 backgroundworker 和 BeginInvoke 相关的示例。
FormP 是 Progressbar-Form。 这有效:
Public Class Form1
Private Delegate Sub delegate_ProgressUpdate(ByVal paramValue As Integer,
ByVal paramMax As Integer)
Private Sub Button1_Click(sender As System.Object,
e As System.EventArgs) Handles Button1.Click
' Test 01:
' Show Progressbar via BGW
' All functions are within Form1
Dim bgw As New BackgroundWorker()
AddHandler bgw.DoWork, AddressOf BGW_Sample01_DoWork
FormP.Show(Me)
bgw.RunWorkerAsync()
End Sub
Private Sub invokeMe_ProgressUpdate(ByVal paramValue As Integer, ByVal paramMax As Integer)
FormP.ProgressBar1.Maximum = paramMax
FormP.ProgressBar1.Value = paramValue
FormP.ProgressBar1.Update()
End Sub
Private Sub BGW_Sample01_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs)
For i As Integer = 1 To 10
Threading.Thread.Sleep(500) ' Test delay
Me.BeginInvoke(New delegate_ProgressUpdate(AddressOf invokeMe_ProgressUpdate),
i, 10)
Next
MessageBox.Show("Fertig")
End Sub
如果我试图让事情更有序地封装在 FormP 中,那是行不通的。
Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
Dim bgw As New BackgroundWorker
AddHandler bgw.DoWork, AddressOf BGW_Sample02_DoWork
FormP.Show(Me)
bgw.RunWorkerAsync()
End Sub
Private Sub BGW_Sample02_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs)
For i As Integer = 1 To 10
Threading.Thread.Sleep(500)
FormP.SetProgress(i, 10)
Next
MessageBox.Show("Fertig")
End Sub
' ########## FormP #################
Public Class FormP
Private Delegate Sub delegate_ProgressUpdate(ByVal value As Integer, ByVal maximum As Integer)
Public Sub SetProgress(ByVal paramValue As Integer, ByVal paramMaximum As Integer)
If Me.InvokeRequired Then
Me.Invoke(New delegate_ProgressUpdate(AddressOf Me.SetProgress), paramValue, paramMaximum)
Else
Me.ProgressBar1.Maximum = paramMaximum
Me.ProgressBar1.Value = paramValue
Me.ProgressBar1.Update()
End If
End Sub
End Class
FormP 不会冻结,但 UI 不会更新。 实际上 Me.InvokeRequired 是错误的,我认为这就是我开始错过一些重要部分的地方。 我在这里尝试了 Form1.InvokeRequired,但它也是错误的。 我的理解是:这里的调用线程就是bgw线程,不管这个线程调用的是什么类的代码…… 好像不是这样?
感谢您的任何想法。
【问题讨论】:
-
您需要停止使用表单的类型名称,就好像它是一个对象引用一样。
FormP.SetProgress(i, 10)语句调用 FormP 的 new 实例上的方法,而不是用户正在查看的实例。 -
非常感谢您……我以前对表单的实例/类名称异常有过奇怪的感觉,但从未冒险研究它。现在它可以工作了,对我来说一切都很好......!
标签: vb.net multithreading progress-bar backgroundworker invokerequired