【问题标题】:Using WebBrowser control in class library在类库中使用 WebBrowser 控件
【发布时间】:2011-10-22 01:40:17
【问题描述】:

我正在尝试在类库中使用此控件,但是当我运行下面的代码时,我没有看到正在向 google 发送请求(使用 fiddler)。

public class WebBrowserTest
{
    public WebBrowserTest()
    {
        var t = new Thread(StartBrowser);
        t.SetApartmentState(ApartmentState.STA);
        t.Start();
    }

    private void StartBrowser()
    {
        WebBrowser web;
        web = new WebBrowser();
        web.Navigate("http://www.google.com");
    }
}

我的猜测是这与线程有关,并且可能线程在控件有机会发送请求之前结束。但我不知道从哪里开始解决这个问题。

解决方案

我发现这个解决方案可行,事件被触发并且主线程等待 STA 线程。

public class WebThread
{
    private WebBrowser web { get; set; }

    public void StartBrowser()
    {
        web = new WebBrowser();
        web.Visible = true;
        web.DocumentCompleted += Web_DocumentCompleted;
        web.ScriptErrorsSuppressed = true;
        web.Navigate("http://www.google.com");

        Application.Run();

        web.Dispose();
    }

    private void Web_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        Debug.Print("Arrived: " + e.Url.ToString());

        if (e.Url.ToString() == "http://www.google.com.au/")
        {
            Application.ExitThread();
        }
    }
}


public class WebBrowserTest
{
    public WebBrowserTest()
    {
        Debug.Print("Thread is starting.");
        var webThread = new WebThread();

        var t = new Thread(webThread.StartBrowser);
        t.SetApartmentState(ApartmentState.STA);
        t.Start();

        while(t.IsAlive)
        {
            Thread.Sleep(5000);
        }

        Debug.Print("Thread has finished.");
    }
}

【问题讨论】:

  • 想想线程结束时变量web会发生什么。
  • UI 控件只能在主前台线程中使用;我不确定在后台线程中创建它时它的行为如何。
  • 请注意代码的一个微妙问题:我们开始导航到 google.com,但随后重定向将我们发送到本地 Google 服务。在 OP 的情况下,它可能是 www.google.com.au,但在你的情况下,它可以是另一个 url(例如google.co.il/?...)并且代码将挂起,因为线程永远不会退出。

标签: c# winforms multithreading webbrowser-control


【解决方案1】:

WebBrowser.Navigate( ... ) 不会阻塞 - 它会在请求发送之前立即返回。由于您的线程函数随后退出,因此您的整个线程结束并带走了您的 WebBrowser 控制权。

如果您只是想下载网页,请查看WebClient 类。它有许多异步方法,这意味着您甚至可能不必创建自己的线程。

【讨论】:

  • WebClient 在这种情况下不起作用,因为我需要执行 javascript。但你的答案是正确的。我在下面添加了我的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-16
  • 1970-01-01
  • 2011-07-28
  • 1970-01-01
  • 1970-01-01
  • 2012-04-16
  • 1970-01-01
相关资源
最近更新 更多