代码之家  ›  专栏  ›  技术社区  ›  madlan

BackgroundWorker线程导致UI挂起

  •  2
  • madlan  · 技术社区  · 14 年前

    我有一个后台工作人员正在检查远程服务器上四个服务的状态。 这是在计时器(5秒)上设置的,如下所示。出于某种原因,它挂起了UI线程,导致应用程序每勾一次就“锁定”一秒钟,我不明白为什么?!

    Private Sub ServiceTimer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ServiceTimer.Tick
    
        _ServiceBGWorker = New System.ComponentModel.BackgroundWorker()
        _ServiceBGWorker.WorkerSupportsCancellation = False
        _ServiceBGWorker.WorkerReportsProgress = False
        AddHandler _ServiceBGWorker.DoWork, New DoWorkEventHandler(AddressOf Me.CheckService)
    
        _ServiceBGWorker.RunWorkerAsync()
        While _ServiceBGWorker.IsBusy
            Application.DoEvents()
        End While
    End Sub
    
    Private Sub CheckService(ByVal sender As Object, ByVal e As DoWorkEventArgs)
    
        If CheckService("Service 3.5") = ServiceControllerStatus.Stopped Then
            PBServiceStatus35.Image = ImgStopIcon
        ElseIf CheckService("Service 3.5") = ServiceControllerStatus.Running Then
    
            PBServiceStatus35.Image = ImgGoIcon
        Else
            PBServiceStatus35.Image = ImgHelpIcon
        End If
    
        If CheckService("Service 3.6") = ServiceControllerStatus.Stopped Then
    
            PBServiceStatus36.Image = ImgStopIcon
        ElseIf CheckService("Service 3.6") = ServiceControllerStatus.Running Then
    
            PBServiceStatus36.Image = ImgGoIcon
        Else
            PBServiceStatus36.Image = ImgHelpIcon
        End If
    
        If CheckService("Service 3.7") = ServiceControllerStatus.Stopped Then
            PBServiceStatus37.Image = ImgStopIcon
        ElseIf CheckService("Service 3.7") = ServiceControllerStatus.Running Then
            PBServiceStatus37.Image = ImgGoIcon
        Else
            PBServiceStatus37.Image = ImgHelpIcon
        End If
    
        If CheckService("Service 4.0") = ServiceControllerStatus.Stopped Then
            PBServiceStatus40.Image = ImgStopIcon
        ElseIf CheckService("Service 4.0") = ServiceControllerStatus.Running Then
            PBServiceStatus40.Image = ImgGoIcon
        Else
            PBServiceStatus40.Image = ImgHelpIcon
        End If
    End Sub
    
    
    Private Function CheckService(ByVal ServiceName As String)
        Dim myController = New ServiceController(ServiceName)
        myController.MachineName = SQLServerName
        myController.Refresh()
        Return myController.Status
    End Function
    
    2 回复  |  直到 13 年前
        1
  •  1
  •   Henk Holterman    14 年前

    这个while循环是完全不必要的:

    While _ServiceBGWorker.IsBusy
        Application.DoEvents()
    End While
    

    不过,我不知道这怎么会引起你在这里的直接问题,但你可以试着不这样做。

    在相关的注释中,最好添加一个已完成的处理程序并检查E.Error状态。可能是有什么东西在抛出异常。使用您当前的代码,您将永远不会知道。

        2
  •  2
  •   Joshua    13 年前

    查看msdn不会有什么坏处 Background Worker Class 文档。一张字条

    您必须小心,不要操作DoWork事件处理程序中的任何用户界面对象。相反,通过ProgressChanged和RunWorkerCompleted事件与用户界面通信。

    因此,不要在DoWork处理程序中操纵PictureBox,而是使用前面提到的处理程序。我编写了两个简单的表单,并从DoWork处理程序加载了一个表单,当从DoWork加载表单时,表单和UI无限期挂起,但其他表单响应正确。