ActiveX control '8856f961-340a-11d0-a96b-00c04fd705a2' cannot be instantiated because the current thread is not in a single-threaded apartment

元气小坏坏 提交于 2019-12-02 04:59:13

问题


I am getting this error when i try to show a form with an webbrowser in it.

ActiveX control '8856f961-340a-11d0-a96b-00c04fd705a2' cannot be instantiated because the current thread is not in a single-threaded apartment

I am calling it by:

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

How can i load this up so it doesn't show me that error?

Thanks.

David

Code update

 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

回答1:


The problem happens because a UI component is being created on a non-UI thread. Here is a simplified version of code which will break with this error message.

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

To correct the problem, you just need to get back to the UI thread before creating the control.

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

So for your example I believe the code would be:

 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



回答2:


Assuming that you are not using the application framework, you need to decorate your Sub Main with the STAThread attribute.

For example:

<STAThread()> _
Public Sub Main()

VB Applications that use the application framework do not have to worry about this attribute since the compiler will apply it automatically.




回答3:


Just searched myself silly, since I am not really doing any threading myself, but I found a solution to my problem with the same error.

Anyway, you also will get this error: "ActiveX control '8856f961-340a-11d0-a96b-00c04fd705a2' cannot be instantiated because the current thread is not in a single-threaded apartment" when you try to use an object on a form (with the WebBrowser Control on it) when that form has not been created yet.

fyi




回答4:


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


来源:https://stackoverflow.com/questions/8783863/activex-control-8856f961-340a-11d0-a96b-00c04fd705a2-cannot-be-instantiated-be

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!