简体   繁体   English

在任务中运行Webbrowser线程

[英]Running a Webbrowser thread in a task

I have a program that runs and starts 2 long running tasks. 我有一个程序可以运行并启动2个长时间运行的任务。 One of the tasks is a web scraper in which I have to use the WebBrowser ActiveX control so that I can get the rendered page. 任务之一是Web抓取工具,其中我必须使用WebBrowser ActiveX控件才能获取渲染的页面。 In order to use the control I have to start a thread so that I can set the apartment state for the message loop. 为了使用控件,我必须启动一个线程,以便为消息循环设置单元状态。 When I do this, the proogram works fine, or at least for the first page that is fetched. 当我这样做时,proogram正常工作,或者至少对于所获取的第一页而言。 Subsequent pages/calls, the webbrowser times out and it's state seems to remain at "uninitialized". 随后的页面/呼叫,Web浏览器超时,并且其状态似乎保持为“未初始化”。 In tracing my code, I never see the "HandleDestroyed" fire for the WebClient. 在跟踪我的代码时,我从没有看到WebClient的“ HandleDestroyed”事件。

What do I need to do to Properly Destroy the WebBrowser control and or my own class in order for it to be reused again. 我需要做些什么才能正确销毁WebBrowser控件和/或我自己的类,以便再次使用它。

public static string AXFetch(string url, string ua)
{
    TestBrowser TB = new TestBrowser();
    Thread th = new Thread(() => TB.MakeLiRequest(url,ua));
    th.SetApartmentState(ApartmentState.STA);
    th.Start();
    th.Join(new TimeSpan(0, 0, 90)); //90 second timeout
    SiteData = TB.DocumentText;
    TB = null;
    return SiteData;
}

class TestBrowser
{
    public string DocumentText = "";
    private bool DocCompleted = false;

    public TestBrowser()
    {

    }

    private void reset_fetch_status()
    {
        this.DocCompleted = false;
        this.DocumentText = "";
    }


    public void MakeLiRequest(string url, string UA)
    {
        reset_fetch_status();
                using (WebBrowser wb = new WebBrowser())
        {
            wb.Visible = false;
            wb.AllowNavigation = true;
            wb.ScriptErrorsSuppressed = true;
            wb.DocumentCompleted += this.wb_DocumentCompleted;
            wb.Navigate(url, "_self", null, "User-Agent: " + UA + "\r\n");
            WaitForPage();
            wb.Url = null;
            wb.DocumentCompleted -= this.wb_DocumentCompleted;
        }
    }

    private void HandleDestroyed(Object sender, EventArgs e)
    {
                //This never seems to fire, I don't knwo why
        Logging.DoLog("You are in the Control.HandleDestroyed event.");

    }

    private bool WaitForPage()
    {
        int timer = 0;
        while (this.DocCompleted == false)
        {
            Application.DoEvents();
            System.Threading.Thread.Sleep(100);
            ++timer;
            if (timer == (PageTimeOut * 10))
            {
                Console.WriteLine("WebBrowser Timeout has been reached");
                Application.Exit();
                return false;
            }

        }
        return true;
    }

    private void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        WebBrowser wb = (WebBrowser)sender;
        if (wb.ReadyState == WebBrowserReadyState.Complete)
        {
            this.DocumentText = wb.DocumentText;
            this.DocCompleted = true;
        }
    }

}

On handle destroyed will only be called by the parent form. 在处理上销毁将仅由父窗体调用。

If you were to try to access from the webbrowser control you would get this error: 如果您尝试从Web浏览器控件访问,则会收到此错误:

Error   1   Cannot access protected member 
'System.Windows.Forms.Control.OnHandleDestroyed(System.EventArgs)' via a 
qualifier of type 'System.Windows.Forms.WebBrowser'; the qualifier must be of type 'stackoverflowpost47036339.Form1' (or derived from it)   

Also you are not hooking it up. 同样,您也没有将其连接起来。 But since you haven't given your web browser any parent form, It can't be called. 但是由于您没有给Web浏览器任何父表单,因此无法调用它。 This is how you would hook it up to the parent form. 这是将其连接到父表单的方式。

     form1.HandleDestroyed += Form1_HandleDestroyed;
    }

    void Form1_HandleDestroyed(object sender, EventArgs e)
    {

    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM