C# WebBrowser未触发事件文档已完成

C# WebBrowser未触发事件文档已完成,c#,.net,C#,.net,因此,我在控制台应用程序中编写了一段代码,它只是从System.Windows.Forms访问一个网站创建一个web浏览器。现在我面临的问题是,如果我使用现成的WebBrowser,DocumentCompleted事件将不会触发,正如您可以看到的,我将一个WebBrowser传递给构造函数 我的理想方法是使用通过构造函数传入的WebBrowser,然后在同一个WebBrowser上导航,由于某些原因,它不会触发DocumentCompleted事件。当使用同一个浏览器时,它会强制我在每次新线程

因此,我在控制台应用程序中编写了一段代码,它只是从
System.Windows.Forms
访问一个网站创建一个web浏览器。现在我面临的问题是,如果我使用现成的WebBrowser,
DocumentCompleted
事件将不会触发,正如您可以看到的,我将一个WebBrowser传递给构造函数

我的理想方法是使用通过构造函数传入的WebBrowser,然后在同一个WebBrowser上导航,由于某些原因,它不会触发
DocumentCompleted
事件。当使用同一个浏览器时,它会强制我在每次新线程内初始化一个新浏览器

public class WebController
{
    private readonly ILogger _logger = new ConsoleLogger(typeof(WebController));

    private WebBrowser _webBrowser;
    private readonly string _webAddress;

    private bool _sendingMessage;
    private string _lastMessage;

    public WebController(WebBrowser webBrowser)
    {
        _webAddress = "https://{username}.example.com/";
    }

    public void SendMessage(string username, string message)
    {
        var thread = new Thread(() =>
        {
            _webBrowser = new WebBrowser();
            _webBrowser.DocumentCompleted += BrowserDocumentCompleted;
            _webBrowser.ScriptErrorsSuppressed = true;
            _webBrowser.Navigate(_webAddress);
            Application.Run();
        });

        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();
    }

    private void BrowserDocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        if (e.Url.AbsolutePath != (sender as WebBrowser)?.Url.AbsolutePath)
        {
            return;
        }

        _logger.Warn("Navigated to: " + e.Url.AbsoluteUri);
    }
}
为什么会这样

下面的代码可以工作,但每次都必须初始化一个新的浏览器

public class WebController
{
    private readonly ILogger _logger = new ConsoleLogger(typeof(WebController));

    private WebBrowser _webBrowser;
    private readonly string _webAddress;

    private bool _sendingMessage;
    private string _lastMessage;

    public WebController(WebBrowser webBrowser)
    {
        _webAddress = "https://{username}.example.com/";
    }

    public void SendMessage(string username, string message)
    {
        var thread = new Thread(() =>
        {
            _webBrowser = new WebBrowser();
            _webBrowser.DocumentCompleted += BrowserDocumentCompleted;
            _webBrowser.ScriptErrorsSuppressed = true;
            _webBrowser.Navigate(_webAddress);
            Application.Run();
        });

        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();
    }

    private void BrowserDocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        if (e.Url.AbsolutePath != (sender as WebBrowser)?.Url.AbsolutePath)
        {
            return;
        }

        _logger.Warn("Navigated to: " + e.Url.AbsoluteUri);
    }
}

您根本不需要线程如果我在自己的线程之外删除代码,那么
BrowserDocumentCompleted
事件将不会发生。您的构造函数为什么有
WebBrowser-WebBrowser
,你能更新它吗?@Dongdong he如果不想锁定UI threadWebBrowser是一种非常清楚它是在什么线程上创建的控件。只有当线程是STA并执行调度程序循环(aka Application.Run)时,它才能够触发事件。我们无法从代码片段中判断什么类型的线程调用WebController构造函数,但我们可以判断它是错误的类型。您已经从SendMessage()方法中了解了正确的类型。