BackgroundWorker冻结了GUI

时间:2013-07-16 03:01:49

标签: vb.net multithreading backgroundworker

我已经阅读了有关此内容的其他帖子,但我似乎无法让它正常工作。

每当我的BackgroundWorker开始工作时,我的函数 API.CheckForUpdate 会导致GUI挂起。我不能点击任何东西。它只会冻结半秒钟,但足以引起注意。

我该如何解决这个问题?我是否应该深入研究 API.CheckForUpdate 并在特定语句上运行单独的线程,或者我是否可以拥有一个处理此问题的全包线程? API.CheckForUpdate不引用Form1中的任何内容。

另外,我认为Form1_Load不是放置RunWorkerAsync调用的最佳位置。哪个地方更好?

'Declarations
Dim ApplicationUpdate As BackgroundWorker = New BackgroundWorker

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    ApplicationUpdate.WorkerSupportsCancellation = True
    ApplicationUpdate.WorkerReportsProgress = True
    AddHandler ApplicationUpdate.DoWork, AddressOf ApplicationUpdate_DoWork
    AddHandler ApplicationUpdate.ProgressChanged, AddressOf ApplicationUpdate_ProgressChanged
    AddHandler ApplicationUpdate.RunWorkerCompleted, AddressOf ApplicationUpdate_RunWorkerCompleted
    ApplicationUpdate.RunWorkerAsync()
End Sub

Private Sub ApplicationUpdate_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
    'Check for an update (get the latest version)
    Dim LatestVersion = API.CheckForUpdate
End Sub

Private Sub ApplicationUpdate_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs)
    'Nothing here
End Sub

Private Sub ApplicationUpdate_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
    'Work completed
    MsgBox("Done")
End Sub

2 个答案:

答案 0 :(得分:1)

它不是后台工作者修复,但如果你不介意四处走动而没有找到答案,你可以像这样编码:

请记住,当您第一次启动一个线程并且您正在模型中进行编码时,您必须将(我)传递给初始线程,因为VB具有"默认表单实例"的概念。对于应用程序命名空间中的每个Form,将在Forms属性下的My命名空间中创建一个默认实例。

,这只是添加一个额外的参数,如此

---------------------- /启动主线程 ------------- ----------------------

Private Sub FindCustomerLocation()
Dim Findcontractor_Thread As New Thread(AddressOf **FindContractor_ThreadExecute**)
Findcontractor_Thread.Priority = ThreadPriority.AboveNormal
Findcontractor_Thread.Start(me)
End Sub

------------------ /正在运行主题/ ---------------

Private Sub **FindContractor_ThreadExecute**(beginform as *NameOfFormComingFrom*)
Dim threadControls(1) As Object
threadControls(0) = Me.XamDataGrid1
threadControls(1) = Me.WebBrowserMap

**FindContractor_WorkingThread**(threadControls,beginform) ' ANY UI Calls back to the Main UI Thread MUST be delegated and Invoked
End Sub

------------------ /如何从线程设置UI调用/ ------------ ---------

Delegate Sub **FindContractor_WorkingThread**(s As Integer,beginform as       *NameOfFormComingFrom*)
Sub **FindContractor_WorkingThreadInvoke**(ByVal s As Integer,beginform as     *NameOfFormComingFrom*)
If beginform.mouse.InvokeRequired Then
Dim d As New FindContractor_WorkingThread(AddressOf        FindContractor_WorkingThreadInvoke)
beginform.Invoke(d, New Object() {s,beginform})
Else
 beginform.Mouse.OverrideCursor = Cursors.Wait

'Do something...

beginform.Mouse.OverrideCursor = Nothing
End If
End Sub

Sources From Pakks Answer Tested!

答案 1 :(得分:0)

尝试在Load事件之外启动该过程。创建一个Timer并在Load事件上启动它,然后处理tick的事件:

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    Timer1.Enabled = False
    ApplicationUpdate.RunWorkerAsync()
End Sub