Потокобезопасный вызов из асинхронной операции в BackgroundWorker

У меня есть некоторый код в BackgroundWorker, который помогает мне предотвратить зависание интерфейса при подключении Bass к аудиопотоку:

Private Sub WorkerConnectToStream_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles WorkerConnectToStream.DoWork
    Bass.BASS_StreamFree(StreamNumber)
    StreamNumber = Bass.BASS_StreamCreateURL(StreamAddr, 0, BASSFlag.BASS_STREAM_STATUS, _downloadProc_, Me.Handle)
    If StreamNumber <> 0 Then
        Bass.BASS_ChannelPlay(StreamNumber, True)
    End If
End Sub

Но я получаю: InvalidOperationException с сообщением: "Имя элемента управления получено из потока, отличного от потока, в котором он был создан". Если для свойства CheckForIllegalCrossThreadCalls задано значение false или я запускаю программу из папки Debug, то все в порядке, но это не лучшее решение.

если я использую:

invoke(sub()
    StreamNumber = Bass.BASS_StreamCreateURL(StreamAddr, 0, BASSFlag.BASS_STREAM_STATUS, _downloadProc_, Me.Handle)
end sub)

тогда это сообщение исчезает, но интерфейс моей формы зависает. Как я могу решить эту проблему? Большое спасибо! Я извиняюсь за мой плохой английский.

1 ответ

Проблема в том, что ваш DoWork работает в фоновом потоке, но вызывает элемент управления в основном потоке. Управление не может этого сделать. Вы должны поднять событие, такое как ReportProgress в вашем Dowork, передать данные и обновить свой контроль там. Это то, что BGW. Это позволяет вам взаимодействовать с элементами управления без написания тонны кода для управления потоками.

Если вы используете какой-то элемент управления для чего-то, и этот элемент управления находится в форме, вместо этого попытайтесь создать его экземпляр в потоке BG и использовать его только в памяти. Я помню, я сделал что-то подобное, и это сработало.

Другие вопросы по тегам