Появилась проблема:
Нужно сделать приложение с многопоточным UI.
В идеале на главную форму должен добавляться UserControl, UI которого будет выполнятся в отдельном потоке.
Может произойти так, что UI этого UserControl "повиснет" (из-за присутствия на нем WebBrowser)
Тогда остальная часть приложения должна продолжать работать.
Сейчас сделал:
Создание экземпляра класса в новом потоке:
- Код: Выделить всё
Dim NUI As New UIThreading
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim thread As New Threading.Thread(AddressOf NUI.createConrol)
thread.SetApartmentState(ApartmentState.STA)
AddHandler NUI.CntReady, AddressOf InvokeCntReady
thread.Start()
End Sub
При запуске потока в режиме STAThread падает эксепшен во время добавления UserControl на основную форму:
Недопустимая операция в нескольких потоках: попытка доступа к элементу управления "DoLooper" не из того потока, в котором он был создан.
Режим MTAThread не подходит, из-за наличия в UserControl WebBrowser (эксепшен при создании UserControl):
Создание экземпляра элемента управления ActiveX "8856f961-340a-11d0-a96b-00c04fd705a2" невозможно: текущий поток не находится в однопоточном контейнере.
Прием ссылки на созданный UI объект:
- Код: Выделить всё
Private Sub cntReady(ByVal wb As Control)
TabControl1.TabPages(0).Controls.Add(wb)
End Sub
Private Delegate Sub DelegatewebReady(ByVal wb As Control)
Public Sub InvokeCntReady(ByVal wb As Control)
If Me.InvokeRequired Then
Dim args As Object() = {wb}
Dim Delegate_cntReady As DelegatewebReady = AddressOf InvokeCntReady
Me.Invoke(Delegate_cntReady, args)
Else
cntReady(wb)
End If
End Sub
Класс для создания экземпляра UserControl:
- Код: Выделить всё
Public Class UIThreading
Property dl As Control
Event CntReady(ByVal wb As Control)
Sub createConrol()
dl = New DoLooper
RaiseEvent CntReady(dl)
dolOop()
End Sub
Sub dolOop()
CType(dl, DoLooper).InvokeStartDoLoop()
End Sub
End Class
UserControl (на нем расположен Button и WebBrowser):
- Код: Выделить всё
Public Class DoLooper
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Do : Loop
End Sub
Private Sub StartDoLoop()
Do : Loop
End Sub
Private Delegate Sub DelegateStartDoLoop()
Public Sub InvokeStartDoLoop()
If Me.InvokeRequired Then
Dim args As Object() = {}
Dim Delegate_StartDoLoop As DelegateStartDoLoop = AddressOf InvokeStartDoLoop
Me.Invoke(Delegate_StartDoLoop, args)
Else
StartDoLoop()
End If
End Sub
End Class
Вопрос: как правильно создать в отдельном потоке экземпляр UserControl, затем поместить его на основную форму чтобы он оставался работать в отдельном потоке и его зависание не мешало работе остальной программе?