2010-08-29 5 views
2

У меня есть работник фона, который проверяет состояние четырех служб на удаленном сервере. Это настройка таймера (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 
+0

Почему вы создаете новый «BackgroundWorker» для каждого тика обслуживания? Разве не лучше было бы повторно использовать существующую «BackgroundWorker», неоднократно вызывая DoWork? –

+0

@Robert: сложно, если работа bgw может занять более 5 секунд. Bgw не является повторным. –

+0

Лучше использовать ThreadPool.QueueUserWorkItem (http://msdn.microsoft.com/en-us/library/system.threading.threadpool.queueuserworkitem.aspx). Если вы сделаете это, у вас не будет накладных расходов на создание потоков. –

ответ

1

Это в то время как петля полностью ненужная:

While _ServiceBGWorker.IsBusy 
    Application.DoEvents() 
End While 

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

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

+0

Я не удивлюсь, если эта петля вызовет проблему. –

+0

Ahh, удаление петли решило проблему - я думал, что это было необходимо для обновления изображений. – madlan

+0

@madian: Но исправьте обработку исключений. Сделайте это привычкой. –

2

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

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

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

+0

Вам не нужно добавлять подпись к сообщениям. [Это уже сделано для вас] (http://stackoverflow.com/faq#signatures). – Joshua

Смежные вопросы