当我尝试在其中显示带有webbrowser的表单时,我收到此错误。
ActiveX控件'8856f961-340a-11d0-a96b-00c04fd705a2'无法实例化,因为当前线程不在单线程单元中
我叫它:
Public Class frmMain
Class Server
Public Shared Sub Main()
Dim aTcpMessaging As IMessagingSystemFactory = New TcpMessagingSystemFactory()
Dim anInputChannel As IInputChannel = aTcpMessaging.CreateInputChannel(theIPforLocal & ":" & thePort)
Dim aStringMessagesFactory As IStringMessagesFactory = New StringMessagesFactory()
Dim aStringMessageReceiver As IStringMessageReceiver = aStringMessagesFactory.CreateStringMessageReceiver()
AddHandler aStringMessageReceiver.MessageReceived, AddressOf StringMessageReceived
aStringMessageReceiver.AttachInputChannel(anInputChannel)
End Sub
Private Shared Sub StringMessageReceived()
Call New frmMM().Show()
End Sub
End Class
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim RelState As Integer = 0
Call frmMain.Server.Main()
lblVer.Text = "V.7"
Pid = 0
End Sub
End Class
如何加载它以便它不会向我显示该错误?
感谢。
大卫
代码更新
Class Server
<STAThread()> Public Sub Main()
Dim aTcpMessaging As IMessagingSystemFactory = New TcpMessagingSystemFactory()
Dim anInputChannel As IInputChannel = aTcpMessaging.CreateInputChannel(theIPforLocal & ":" & thePort)
Dim aStringMessagesFactory As IStringMessagesFactory = New StringMessagesFactory()
Dim aStringMessageReceiver As IStringMessageReceiver = aStringMessagesFactory.CreateStringMessageReceiver()
AddHandler aStringMessageReceiver.MessageReceived, AddressOf StringMessageReceived
aStringMessageReceiver.AttachInputChannel(anInputChannel)
End Sub
Private Shared Sub StringMessageReceived()
Call New frmMM().Show()
End Sub
End Class
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim RelState As Integer = 0
Call frmMain.Server.Main() '<-- the error now
lblVer.Text = "V.7"
Pid = 0
End Sub
End Class
答案 0 :(得分:4)
问题发生的原因是在非UI线程上创建了UI组件。 这是一个简化版本的代码,它将破坏此错误消息。
Imports System.ComponentModel
Public Class Form1
Private _ThreadedProcesss As ThreadedProcess
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
_ThreadedProcesss = New ThreadedProcess()
_ThreadedProcesss.Start()
End Sub
Public Class ThreadedProcess
Private _thread As System.Threading.Thread
Public Sub Start()
_thread = New System.Threading.Thread(AddressOf ThreadEntryPoint)
_thread.Name = "Testing thread"
_thread.Start()
End Sub
Private Sub ThreadEntryPoint(status As Object)
Dim wb As New WebBrowser()
wb.Dock = DockStyle.Fill
wb.Visible = True
wb.DocumentText = "Hello world"
End Sub
End Class
End Class
要解决此问题,您只需在创建控件之前返回UI线程。
Imports System.ComponentModel
Public Class Form1
Private _ThreadedProcesss As ThreadedProcess
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
_ThreadedProcesss = New ThreadedProcess(New EventHandler(AddressOf ThreadedProcess_Create))
_ThreadedProcesss.Start()
End Sub
Private Sub ThreadedProcess_Create(sender As Object, e As System.EventArgs)
If (Me.InvokeRequired) Then
Me.Invoke(New EventHandler(AddressOf ThreadedProcess_Create), {sender, e})
Else
Dim wb As New WebBrowser()
Me.Controls.Add(wb)
wb.Dock = DockStyle.Fill
wb.Visible = True
wb.DocumentText = "Hello world"
End If
End Sub
Public Class ThreadedProcess
Private _thread As System.Threading.Thread
Private _callback As EventHandler
Public Sub New(callback As EventHandler)
_callback = callback
End Sub
Public Sub Start()
_thread = New System.Threading.Thread(AddressOf ThreadEntryPoint)
_thread.Name = "Testing thread"
_thread.Start()
End Sub
Private Sub ThreadEntryPoint(status As Object)
_callback.Invoke(Me, EventArgs.Empty)
End Sub
End Class
End Class
因此,对于您的示例,我相信代码将是:
Class Server
Private _callback as EventHandler
Public Sub Main(callback as EventHandler)
_callback = callback
Dim aTcpMessaging As IMessagingSystemFactory = New TcpMessagingSystemFactory()
Dim anInputChannel As IInputChannel = aTcpMessaging.CreateInputChannel(theIPforLocal & ":" & thePort)
Dim aStringMessagesFactory As IStringMessagesFactory = New StringMessagesFactory()
Dim aStringMessageReceiver As IStringMessageReceiver = aStringMessagesFactory.CreateStringMessageReceiver()
AddHandler aStringMessageReceiver.MessageReceived, AddressOf StringMessageReceived
aStringMessageReceiver.AttachInputChannel(anInputChannel)
End Sub
Private Sub StringMessageReceived()
_callback.Invoke(Me, EventArgs.Empty)
End Sub
End Class
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim RelState As Integer = 0
Call frmMain.Server.Main(new EventHandler(AddressOf Server_MessageReceived)) '<-- the error now
lblVer.Text = "V.7"
Pid = 0
End Sub
Private Sub Server_MessageReceived(sender as Object, e As EventArgs)
If (Me.InvokeRequired) Then
Me.Invoke(New EventHandler(AddressOf Server_MessageReceived), {sender, e})
Else
Call New frmMM().Show()
End If
End Sub
End Class
答案 1 :(得分:1)
假设您没有使用应用程序框架,则需要使用STAThread属性装饰Sub Main
。
例如:
<STAThread()> _
Public Sub Main()
使用应用程序框架的VB应用程序不必担心此属性,因为编译器将自动应用它。
答案 2 :(得分:1)
我只是傻傻地搜索自己,因为我自己并没有真正做任何线程,但我找到了一个解决我的问题的方法同样的错误。
无论如何,你也会得到这个错误:&#34; ActiveX控件&#39; 8856f961-340a-11d0-a96b-00c04fd705a2&#39;无法实例化,因为当前线程不在单线程单元中#34;当您尝试在窗体上使用对象(使用WebBrowser控件)时尚未创建该窗体。
FYI
答案 3 :(得分:0)
Class Server
<STAThread()> Public Sub Main()
Dim aTcpMessaging As IMessagingSystemFactory = New TcpMessagingSystemFactory()
Dim anInputChannel As IInputChannel = aTcpMessaging.CreateInputChannel(theIPforLocal & ":" & thePort)
Dim aStringMessagesFactory As IStringMessagesFactory = New StringMessagesFactory()
Dim aStringMessageReceiver As IStringMessageReceiver = aStringMessagesFactory.CreateStringMessageReceiver()
AddHandler aStringMessageReceiver.MessageReceived, AddressOf StringMessageReceived
aStringMessageReceiver.AttachInputChannel(anInputChannel)
End Sub
Private Shared Sub StringMessageReceived()
Dim t As New Threading.Thread(AddressOf ShowFP)
t.SetApartmentState(Threading.ApartmentState.STA)
t.Start()
End Sub
End Class
Private Shared Sub ShowFP()
Dim ShowFP As New frmFPVid
ShowFP.ShowDialog()
End Sub