Question create a browser in backgroundworker thread

Zexor

Well-known member
Joined
Nov 28, 2008
Messages
520
Programming Experience
3-5
can i create a webbrowser in backgroundworker thread in a function and dispose it before function ends?
When i try to make a webbrowser, it say activex control cannot be instantiated because the current thread is not in a single threaded apartment.
if i put the webbrowser in the progresschanged, the backgrounderworker thread will end before progresschanged end. I need the webbrowser be done before all threads are done.
I use the webbrowser to login to the website and get the cookie. I tried webrequest but that gave me 417 error.
Now i am trying to move all of it into backgroundworker.
 
Last edited:
If you want to be able to create a WebBrowser on a secondary thread then you must create a Thread object yourself, set its ApartmentState property to STA and then Start it.

That said, you really should avoid using controls for anything other than interacting with the user if possible. You should be using a WebClient and/or WebRequest for this if possible. Most likely it would work but you're just doing it wrong. If you show us what you tried with the WebRequest then we may be able to help you fix it.
 
i used this same format on a different site and it works fine for getting the cookie. postdata would be different. i added the expect100continue line cause of the 417 error.

VB.NET:
    Private Function getCookieContainer() As CookieContainer
        Dim username As String = "username"
        Dim password As String = "password"
        Dim postData As String = "formhash=5dab978b&referer=&cookietime=2592000&username=" + username + "&password=" + password + "&questionid=0&answer=&loginsubmit=%E6%8F%90+%C2%A0+%E4%BA%A4"


        Dim tempCookies As New CookieContainer
        Dim encoding As New System.Text.UTF8Encoding
        Dim byteData As Byte() = encoding.GetBytes(postData)
        ServicePointManager.Expect100Continue = False   'stop using header expect 100 continue


        Dim postReq As HttpWebRequest = DirectCast(WebRequest.Create("http://abcde.com/logging.php?action=login"), HttpWebRequest)
        postReq.Method = "POST"
        postReq.KeepAlive = True
        postReq.CookieContainer = tempCookies
        postReq.ContentType = "application/x-www-form-urlencoded"
        postReq.Referer = "http://abcde.com/index.php"
        postReq.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.3) Gecko/20100401 Firefox/4.0 (.NET CLR 3.5.30729)"
        postReq.ContentLength = byteData.Length


        Dim postreqstream As IO.Stream = postReq.GetRequestStream()
        postreqstream.Write(byteData, 0, byteData.Length)
        postreqstream.Close()
        Dim postresponse As HttpWebResponse


        postresponse = DirectCast(postReq.GetResponse(), HttpWebResponse) '417 error


        tempCookies.Add(postresponse.Cookies)
        Return tempCookies


    End Function
 
Last edited:
Is this the same as using a backgroundworker? Essentially i am just trying to convert the sub scan to a background thread.

VB.NET:
    Dim scanThreadDelegate As New Threading.ThreadStart(AddressOf scan)
    Dim scanThread As New System.Threading.Thread(scanThreadDelegate) With {.ApartmentState = Threading.ApartmentState.STA}
.
.
.
     scanThread.Start(.Name)
how do you pass the .name to the scan?
 
Last edited:
It's not the same as using a BackgroundWorker. BackgroundWorker is a class that hides many of the details of multi-threading your life easier. Internally, it uses the ThreadPool, which is a class that maintains a pool of threads that can be used by the system or by your code to perform background tasks. All asynchronous methods perform their tasks on ThreadPool threads. The BackgroundWorker raises its DoWork event on a ThreadPool thread. You can't use a ThreadPool thread in this case because they are all multithreaded apartment. That's why you have to create your own Thread object and set its ApartmentState.

Actually, I just checked the documentation for the ApartmentState property and apparently it has been deprecated. You need to call the SetApartmentState method instead.
 
Back
Top