WebBrowser控件抛出看似随机的NullReferenceException

几天后,我正在开发基于WebBrowser的webscraper。 在使用Threads和DocumentCompleted事件的几个原型之后,我决定尝试看看我是否可以创建一个简单易懂的Webscraper。

目标是创建一个不涉及实际Thread对象的Webscraper。 我希望它按顺序步骤工作(即转到url,执行操作,转到其他url等等)。

这是我到目前为止所得到的:

public static class Webscraper { private static WebBrowser _wb; public static string URL; //WebBrowser objects have to run in Single Thread Appartment for some reason. [STAThread] public static void Init_Browser() { _wb = new WebBrowser(); } public static void Navigate_And_Wait(string url) { //Navigate to a specific url. _wb.Navigate(url); //Wait till the url is loaded. while (_wb.IsBusy) ; //Loop until current url == target url. (In case a website loads urls in steps) while (!_wb.Url.ToString().Contains(url)) { //Wait till next url is loaded while (_wb.IsBusy) ; } //Place URL URL = _wb.Url.ToString(); } } 

我是一名新手程序员,但我认为这是非常简单的代码。 这就是为什么我讨厌由于某种原因程序在这段代码中抛出NullReferenceException的事实:

  _wb.Url.ToString().Contains(url) 

我刚刚调用_wb.Navigate()方法,因此NullReference不能在_wb对象本身。 所以我唯一能想到的是_wb.Url对象是null。 但while _wb.IsBusy()循环应该可以防止这种情况发生。

那么发生了什么,我该如何解决?

忙线等待( while (_wb.IsBusy) ; )在UI线程上是不太可取的。 如果您使用.Net 4.5的新functionasync / await ,您可以获得类似的效果( 即转到url,执行操作,转到其他url等等 )您想要的

 public static class SOExtensions { public static Task NavigateAsync(this WebBrowser wb, string url) { TaskCompletionSource tcs = new TaskCompletionSource(); WebBrowserDocumentCompletedEventHandler completedEvent = null; completedEvent = (sender, e) => { wb.DocumentCompleted -= completedEvent; tcs.SetResult(null); }; wb.DocumentCompleted += completedEvent; wb.ScriptErrorsSuppressed = true; wb.Navigate(url); return tcs.Task; } } async void ProcessButtonClick() { await webBrowser1.NavigateAsync("http://www.stackoverflow.com"); MessageBox.Show(webBrowser1.DocumentTitle); await webBrowser1.NavigateAsync("http://www.google.com"); MessageBox.Show(webBrowser1.DocumentTitle); }