Фоновый поток, вызывающий зависание пользовательского интерфейса - PullRequest
2 голосов
/ 30 августа 2010

У меня есть фоновый работник, который проверяет состояние четырех служб на удаленном сервере. Это настройка таймера (5 секунд), как показано ниже. По какой-то причине он зависает в потоке пользовательского интерфейса, заставляя приложение «блокировать» на секунду каждый тик, я не могу понять, почему?!

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 ]

2 голосов
/ 27 октября 2011

Не мешало бы просмотреть документацию MSDN Background Worker Class .Примечание, которое гласит

Вы должны быть осторожны, чтобы не манипулировать объектами пользовательского интерфейса в обработчике событий DoWork.Вместо этого общайтесь с пользовательским интерфейсом с помощью событий ProgressChanged и RunWorkerCompleted.

Поэтому вместо манипулирования вашей картинкой в ​​обработчике DoWork используйте вышеупомянутые обработчики.Я написал две простые формы и загрузил одну из обработчика DoWork, а форма и пользовательский интерфейс зависают на неопределенное время, когда форма загружается из DoWork, но правильно реагирует на другие.

1 голос
/ 30 августа 2010

Этот цикл while совершенно не нужен:

While _ServiceBGWorker.IsBusy
    Application.DoEvents()
End While

Хотя я не понимаю, как это может привести к вашей прямой проблеме, но вы можете попробовать и без нее.

В связанной заметке было бы неплохо добавить обработчик Completed и проверить состояние e.Error.Может быть, что-то бросает исключения.С вашим текущим кодом вы никогда не узнаете.

...