Malasuerte94 Malasuerte94 - 4 months ago 12
Vb.net Question

Getting an error when creating a WebBrowser in a new thread vb.net

I'm trying to create a new webbrowser with a new thread, but when I try to run the program I'm always getting the following error:

enter image description here
Can someone help me fix this error please? Here's my code:

Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click


Dim curFile1 As String = TextBox4.Text
If (File.Exists(curFile1)) Then
MsgBox("Ok")
Else
MsgBox("Please a User Agent file", MsgBoxStyle.Critical, "Error")
Exit Sub
End If

Dim curFile2 As String = TextBox1.Text
If (File.Exists(curFile2)) Then
MsgBox("Ok")
Else
MsgBox("Please a IP file", MsgBoxStyle.Critical, "Error")
Exit Sub
End If

Try
' Open the file using a stream reader.
Using sr As New StreamReader(curFile2)
' Read the stream to a string and write the string to the console.
ip_text = File.ReadAllLines(curFile2)
End Using
Catch er As Exception
MsgBox("The file could not be read: IP", MsgBoxStyle.Critical, "Error")
Exit Sub
End Try


Try
' Open the file using a stream reader.
Using sr2 As New StreamReader(curFile1)
' Read the stream to a string and write the string to the console.
user_text = File.ReadAllLines(curFile1)
End Using
Catch er As Exception
MsgBox("The file could not be read: User Agent", MsgBoxStyle.Critical, "Error")
Exit Sub
End Try


nr = 0
For Each ip As String In ip_text

MsgBox(ip)

trd = New Thread(AddressOf make_it)
trd.IsBackground = True
trd.Start()

nr = nr + 1
Next


End Sub

Private Sub make_it()
Dim decible = New WebBrowser()
web_panel.Controls.Add(decible)

decible.Name = "browser" & nr
Dim RandomIpAddress As String = user_text(GetRandom(user_text.Length))
MsgBox(RandomIpAddress)

ChangeUserAgent(RandomIpAddress)
decible.Navigate("http://www.whatsmyuseragent.com/")

End Sub


Help is greatly appreciated, stuck on this error for days now.

Answer

You get the error because the new thread(s) that you create are generally in a so called Multithreaded Apartment (MTA). According to the error the WebBrowser control can only be created on a thread that is in a Single-threaded Apartment (STA, an example being the UI thread).

Changing your thread's apartment is not recommended because it must be MTA in order to be multithreaded alongside of the UI thread.

This leaves you with pretty much only one option: create and modify the control on the UI thread only, and do the other heavy lifting in your new thread.

I would create the control on the UI thread, and in the end of the thread I would perform invocation to run the navigating code.

Solution for .NET Framework 4.0 or higher:

In your loop:

Dim decible = New WebBrowser()
decible.Name = "browser" & nr
web_panel.Controls.Add(decible)

trd = New Thread(AddressOf make_it)
trd.IsBackground = True
trd.Start(decible) 'Passing the web browser as a parameter.

The make_it method:

Private Sub make_it(ByVal decible As WebBrowser)
    Dim RandomIpAddress As String = user_text(GetRandom(user_text.Length))
    MsgBox(RandomIpAddress)

    ChangeUserAgent(RandomIpAddress)

    If Me.InvokeRequired = True Then
        Me.Invoke(Sub() decible.Navigate("http://www.whatsmyuseragent.com/"))
    Else
        decible.Navigate("http://www.whatsmyuseragent.com/")
    End If

End Sub

Solution for .NET Framework 3.5 or lower:

In your loop (this is the same as above):

Dim decible = New WebBrowser()
decible.Name = "browser" & nr
web_panel.Controls.Add(decible)

trd = New Thread(AddressOf make_it)
trd.IsBackground = True
trd.Start(decible) 'Passing the web browser as a parameter.

The make_it method:

Private Sub make_it(ByVal decible As WebBrowser)
    Dim RandomIpAddress As String = user_text(GetRandom(user_text.Length))
    MsgBox(RandomIpAddress)

    ChangeUserAgent(RandomIpAddress)

    NavigateWebBrowser(decible, "http://www.whatsmyuseragent.com/")

End Sub

Delegate Sub NavigateDelegate(ByVal Browser As WebBrowser, ByVal Url As String)

Private Sub NavigateWebBrowser(ByVal Browser As WebBrowser, ByVal Url As String)
    If Me.InvokeRequired = True Then
        Me.Invoke(New NavigateDelegate(AddressOf NavigateWebBrowser), Browser, Url)
    Else
        Browser.Navigate(Url)
    End If
End Sub