在任务

时间:2017-10-31 13:11:53

标签: c# multithreading task-parallel-library webbrowser-control

我有一个程序可以运行并启动2个长时间运行的任务。其中一个任务是Web scraper,我必须使用WebBrowser ActiveX控件才能获得呈现的页面。为了使用控件,我必须启动一个线程,以便我可以为消息循环设置单元状态。当我这样做时,程序工作正常,或至少对于提取的第一页。随后的页面/电话,网络浏览器超时,它的状态似乎仍然未被初始化"未初始化"。在跟踪我的代码时,我从未看到" HandleDestroyed"为WebClient开火。

我需要做什么才能正确销毁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;
        }
    }

}

1 个答案:

答案 0 :(得分:0)

在被销毁的句柄上只会被父表单调用。

如果您尝试从webbrowser控件访问,则会收到此错误:

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)   

你也没有把它挂起来。但是,由于您没有为您的Web浏览器提供任何父表单,因此无法调用它。这就是你将它连接到父表单的方式。

     form1.HandleDestroyed += Form1_HandleDestroyed;
    }

    void Form1_HandleDestroyed(object sender, EventArgs e)
    {

    }