【发布时间】:2018-09-24 20:14:12
【问题描述】:
我只是想知道是否可以以这种“实验性”的方式管理 Windows 窗体进度条:
- 我想在主窗体中控制栏,因为我有一个线程执行 WorkerClass 对象中的代码,该对象包含一个函数 doWork 来执行繁重的计算。
- WorkerClass 包含两个成员变量,它们由 doWork 函数更新,可从表单访问以同步线程并继续跟踪已完成的工作。
- 由于我需要为这些成员变量提供线程安全,我在主窗体中构建了两个 synclocking 对象并将它们传递给 doWork 函数
-
doWork 函数返回一个主窗体完成工作所需的值,所以我发现我必须告诉窗体线程等待返回值的事实很棘手。
这是 WorkerClass 代码:
Public Class WorkerClass Private mBarValue As Integer Private mStartNow As Boolean Public ReadOnly Property BarValue Get Return mBarValue End Get End Property Public ReadOnly Property StartNow As Boolean Get Return mStartNow End Get End Property Public Sub New() mBarValue = 0 mStartNow = False End Sub Public Function doWork(ByRef list As ArrayList) As Integer SyncLock (list.Item(0)) mStartNow = True End SyncLock 'Do your work and update status For i As Integer = 0 To 99 Thread.Sleep(10) SyncLock (list.Item(1)) mBarValue += 1 End SyncLock Next SyncLock (list.Item(0)) mStartNow = False End SyncLock Return 1000 End Function End Class
这是主要的表单代码:
Public Class Form1
Private lock As Object
Private lock2 As Object
Private integerNeeded As Integer
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Me.lock = New Object()
Me.lock2 = New Object()
Dim wc As New WorkerClass()
Dim wT As New Thread(AddressOf workerThread)
Me.ProgressBar1.Value = 0
Me.ProgressBar1.Show()
wT.Start(wc)
Dim canStart As Boolean = False
While Not canStart
SyncLock (lock)
canStart = wc.StartNow
End SyncLock
End While
Debug.WriteLine("Start")
'Bar updater
Dim currentProgress As Integer = 0
While canStart
SyncLock (lock2)
currentProgress = wc.BarValue
End SyncLock
If currentProgress Mod Me.ProgressBar1.Step = 0 Then
Me.ProgressBar1.PerformStep()
Debug.WriteLine(Me.ProgressBar1.Value)
End If
SyncLock (lock)
canStart = wc.StartNow
End SyncLock
End While
While wT.IsAlive 'Wait until the thread is done. Need to guarantee the value is returned
End While
Debug.WriteLine("End")
Me.ProgressBar1.Hide()
REM Rest of the code with integerNeeded here...
End Sub
Private Sub workerThread(wc As Object)
Dim locks As New ArrayList()
locks.Add(lock)
locks.Add(lock2)
integerNeeded = wc.doWork(locks)
End Sub
End Class
我的问题:这似乎可行,但我发现它很慢,甚至我也不太信任它,有没有更有效的方法来实现它?我已经搜索了示例,但我没有找到任何线程在不同的类中执行代码的东西。
非常感谢!
【问题讨论】:
标签: .net vb.net multithreading winforms thread-safety