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

后端 未结 4 2045
予麋鹿
予麋鹿 2021-01-22 20:54

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 becau

相关标签:
4条回答
  • 2021-01-22 21:29

    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
    
    0 讨论(0)
  • 2021-01-22 21:37
    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
    
    0 讨论(0)
  • 2021-01-22 21:38

    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

    0 讨论(0)
  • 2021-01-22 21:40

    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.

    0 讨论(0)
提交回复
热议问题