后台工作线程导致 UI 挂起

发布于 2024-09-16 14:40:33 字数 2196 浏览 1 评论 0原文

我有一个后台工作人员正在检查远程服务器上四个服务的状态。 这是在计时器(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

I have a background worker that's checking the status of four services on a remote server.
This is setup on a timer (5 Seconds) as below. For some reason it's hanging the UI thread causing the application to 'lock' for a second each tick, I cannot work out why?!

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

白色秋天 2024-09-23 14:40:34

查看 MSDN 后台工作器类文档。一条注释写着

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

因此,不要在 DoWork 处理程序中操作图片框,而是使用上述处理程序。我编写了两个简单的表单,并从 DoWork 处理程序加载了一个,当从 DoWork 加载该表单时,该表单和 UI 无限期挂起,但从其他表单正确响应。

It wouldn't hurt to review the MSDN Background Worker Class documentation. A note that reads

You must be careful not to manipulate any user-interface objects in your DoWork event handler. Instead, communicate to the user interface through the ProgressChanged and RunWorkerCompleted events.

So instead of manipulating your picturebox in your DoWork handler, use the aforementioned handlers. I wrote two simple forms and loaded one from a DoWork handler and the Form and UI hang indefinitely when the Form is loaded from DoWork, but responds properly from the others.

弱骨蛰伏 2024-09-23 14:40:34

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

While _ServiceBGWorker.IsBusy
    Application.DoEvents()
End While

虽然我不明白它如何会导致你的直接问题,但你可以尝试不使用。

与此相关的是,最好添加一个 Completed 处理程序并检查 e.Error 状态。也许有什么东西抛出异常。使用您当前的代码,您永远不会知道。

This while loop is completely unnecessary:

While _ServiceBGWorker.IsBusy
    Application.DoEvents()
End While

I don't see how it could cause your direct problem here though, but you might try without.

On a related note, it would be a good idea to add a Completed handler and check the e.Error status. Maybe something is throwing exceptions. With your current code, you will never know.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文