【发布时间】:2013-08-01 15:14:08
【问题描述】:
我为我的应用程序实现了一个 BGW,希望加快启动窗口的加载时间(40 多个控件)
我不会发布我的整个代码,因为它太长了,但会给你代码的要点。我将需要时间完成的大函数调用与少数控件一起拆分,并将它们移到 BGW 中,希望异步加载控件以帮助加快进程。
据了解,我必须将 UI 更改代码移动到 ProgressChanged 事件或 RunWorkerCompleted 事件,我已经这样做了。我最初将所有代码都扔到了 DoWork 事件中,它非常快,但发现它不安全,所以我重新设计了它以将所有与 UI 相关的 oode 移动到 ProgressChanged。现在几乎没有那么快了,而且 BGW 控件似乎要等到 UI 线程完成后再更改 BGW_ProgressCHanged 事件中的控件。当我对 DoWork 进行所有更改时,我从未见过两者之间的这种“滞后”。我能做些什么呢?或者我至少可以让 BGW 实时更新控件,而不是等待所有控件完成后再更新所有控件?
响应速度较低,并且会锁定窗口以等待 BGW 控件更新。只是寻找可能发生的事情
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
SyncLock <globalVar>
BackgroundWorker1.ReportProgress(0, "Tom")
End SyncLock
End Sub
Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As System.Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
Dim value As String = DirectCast(e.UserState, String)
Select Case e.ProgressPercentage
Case 0
lblName.text = value
lblName.Visible = true
End Select
End Sub
【问题讨论】:
-
您在一个对象上有一个
SyncLock。如果 UI 线程还试图在BackgroundWorker运行时锁定该对象,则会被阻止。 -
我的印象是 SyncLock 将是在另一个线程中安全地使用共享全局变量的唯一方法。有没有更好的办法?
-
根本不允许
BackgroundWorker访问该变量。返回结果并更新RunWorkerCompleted事件处理程序中的变量。 -
我正在努力理解。我拥有 BGW_DoWork 事件中所有控件的所有逻辑,为了使用该逻辑,我需要使用该变量,该变量只能在整个项目中声明一次。
-
BackgroundWorker可以对变量的副本进行操作。您也可以尝试将锁定的范围最小化到实际访问它的语句,而不是为整个DoWork事件处理程序锁定它。
标签: vb.net multithreading winforms backgroundworker