BackGroundWorker RunWorkerCompleted Событие иногда не вызывается - PullRequest
0 голосов
/ 02 февраля 2012

Я вижу странное поведение, когда событие RunWorkerCompleted для одного из двух запущенных мной потоков не вызывается в зависимости от того, как я их вызываю.Посмотрите код ниже и два метода запуска потоков: good () и bad ().

Public Class Form1

  Private WithEvents bw As System.ComponentModel.BackgroundWorker
  Private WithEvents bw2 As System.ComponentModel.BackgroundWorker
  Private starts As Integer = 0

  Private Sub bw_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bw.DoWork
    starts += 1
    Threading.Thread.Sleep(e.Argument)
  End Sub

  Private Sub bw_Completed(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bw.RunWorkerCompleted
    MessageBox.Show("Ending " + starts.ToString())
  End Sub

  Private Sub bad()
    bw = New System.ComponentModel.BackgroundWorker()
    bw.RunWorkerAsync(5000)

    Threading.Thread.Sleep(500)

    bw = New System.ComponentModel.BackgroundWorker()
    bw.RunWorkerAsync(5)
  End Sub

  Private Sub good()
    bw2 = New System.ComponentModel.BackgroundWorker()
    AddHandler bw2.DoWork, AddressOf bw_DoWork
    AddHandler bw2.RunWorkerCompleted, AddressOf bw_Completed
    bw2.RunWorkerAsync(500)

    bw2 = New System.ComponentModel.BackgroundWorker()
    AddHandler bw2.DoWork, AddressOf bw_DoWork
    AddHandler bw2.RunWorkerCompleted, AddressOf bw_Completed
    bw2.RunWorkerAsync(5)
  End Sub

  Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    'good()
    bad()
  End Sub
End Class

В обоих случаях событие DoWork вызывается для обоих потоков.Но в случае bad () только второй поток запускает событие RunWorkerCompleted.Это очевидно из-за двух разных способов, которыми я использую VB для обработки событий здесь.Я ищу объяснение этого поведения, желательно со ссылкой на некоторую документацию, которая могла бы помочь мне лучше понять, как эти события обрабатываются в VB.Мне кажется странным, что простое повторное использование имени переменной здесь, по-видимому, либо уничтожает поток до его завершения, либо просто заставляет его прекратить запуск событий.

1 Ответ

1 голос
/ 03 февраля 2012

Где задокументирована эта автоматическая отмена подписки?

В спецификации языка Visual Basic документ, который вы можете загрузить из Microsoft .Глава 9.6.2 «Переменные WithEvents» говорит следующее:

Неявное свойство, созданное объявлением WithEvents, заботится о подключении и отключении соответствующих обработчиков событий.Когда значение присваивается переменной, свойство сначала вызывает метод удаления для события в экземпляре, который в данный момент находится в переменной (отсоединение существующего обработчика событий, если есть) .Затем выполняется присваивание, и свойство вызывает метод add для события в новом экземпляре в переменной (подключая новый обработчик событий).

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

...