WebBrowser control: “Specified cast is not valid.”

不羁的心 提交于 2019-12-05 05:00:06

问题


I used a WebBrowser control to navigate to the login page for a WordPress blog. The page loads fine but whenever I try to access the WebBrowser from a thread. I get a specific cast is not valid exception. Also when debugging, everything freezes up for around 5 seconds. When debugging and I try to access the control. I get timed out errors on all of the member variables.

//in constructor of main form
Thread.CurrentThread.ApartmentState = ApartmentState.STA;
this.CheckForIllegalCrossThreadCalls = false;

mainThreadHandle = new Thread(mainThread);
mainThreadHandle.Start();

private void mainThread()
{
    wbMain.Navigate("http://example.com/");

    //navigating is set to false in the document complete event.
    navigating = true;

    while (navigating == true)
        Thread.Sleep(5000);

    try
    {
        //Where I get the issues
        MessageBox.Show(wbMain.DocumentText);
    }
    catch (Exception e)
    {

    }

    Thread.Sleep(1000);
}

回答1:


WebBrowser is a COM component under the hood. An apartment threaded one, COM takes care of calling its methods in a thread-safe way. Your Navigate() call works for that reason, it is actually executed on the UI thread. What doesn't work is the DocumentText property, it is implemented in the .NET wrapper and they somewhat fumbled the code. It bombs when the COM interop support in the CLR notices that a thread in the MTA tries to access a property of a component that lives on an STA.

Your call to SetApartmentState() isn't correct. It is made on the wrong thread, the UI thread already is STA. Also the reason it doesn't bomb, you cannot change the apartment state of a thread after it is started. You must call it on the Thread object you created. It still doesn't solve your problem, two STA threads are not compatible.

Two basic ways to solve your problem. The first one is that you create the WebBrowser object itself on a separate STA thread. The code in this answer shows you how to do that.

The browser you create that way cannot also be visible on your form. Which is the second way, marshal the call yourself with Control.Invoke(). Doing this is however pretty pointless, all of your code executes on the UI thread anyway, you get no concurrency. There is no free lunch here. Running it on a thread only gives you headaches. If you need time to process the document text then run that code on a separate thread.




回答2:


Why not use event model when work with WebBrowser control?

Navigating, Navigated, ProgressChanged, DocumentCompleted



来源:https://stackoverflow.com/questions/5848839/webbrowser-control-specified-cast-is-not-valid

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