C#NullReference但Visual Studio显示对象不为null

时间:2018-04-26 21:13:56

标签: c# selenium selenium-webdriver

当我在示例代码中按下表单上的停止按钮时,driver.Quit()调用会抛出NullReference异常,但是当我将它悬停在IDE中的对象上,当它在异常中断时,该对象不是空。

此外,在null检查条件下调用driver.Quit()。

public partial class ProxyScraperForm : Form
{

    private BindingList<IProxyScraperSite> sites = new BindingList<IProxyScraperSite>();
    private List<IWebDriver> activeDrivers = new List<IWebDriver>();

    public BindingList<IProxyScraperSite> Sites { get { return this.sites; } }

    public ProxyScraperForm()
    {
        InitializeComponent();

        sites.Add(new ProxyScraperSiteUsProxyOrg());
        sites.Add(new ProxyScraperSiteFreeProxyListNet());
        sites.Add(new ProxyScraperSiteFreeProxyListsNet());
        sites.Add(new ProxyScraperSiteHideMyName());
        sites.Add(new ProxyScraperSiteHidester());
        scraperDataGridView.DataSource = sites;
    }

    private void scrapeButton_Click(object sender, EventArgs e)
    {
        foreach (var site in sites)
        {
            Task.Run(async () =>
            {
                var driver = SeleniumUtility.CreateDefaultFirefoxDriver();
                activeDrivers.Add(driver);
                await site.ScrapeAsync(driver);
                driver.Quit();
                activeDrivers.Remove(driver);
            });
        }
    }

    private void stopButton_Click(object sender, EventArgs e)
    {
        foreach (var driver in activeDrivers)
        {
            if (driver != null)
            {
                driver.Quit();
            }
        }

        activeDrivers.Clear();

        foreach (var site in sites)
        {
            site.Status = "Idle";
        }
    }

    private void proxyScraperForm_FormClosing(object sender, FormClosingEventArgs e)
    {
        stopButton.PerformClick();
        this.DialogResult = DialogResult.Cancel;
    }
}

Inside site.ScrapeAsync

public class ProxyScraperSiteHideMyName : ProxyScraperSiteBase
{
    public ProxyScraperSiteHideMyName() { SiteName = "HideMyName"; }

    public override Task ScrapeAsync(IWebDriver driver, PauseOrCancelToken pct = null)
    {
        return Task.Run(async () =>
        {
            try
            {
                Status = "Starting";
                driver.Navigate().GoToUrl("https://hidemy.name/en/proxy-list/");
                var wait = new WebDriverWait(driver, new TimeSpan(0, 0, 30));
                var lastPageLinkElement = wait.Until(extras.ExpectedConditions.ElementIsVisible((By.XPath("/html/body/div[1]/div/section[1]/div/div[4]/ul/li[10]/a"))));
                var totalPages = Int32.Parse(lastPageLinkElement.Text);
                for (int i = 0; i < totalPages; i++)
                {
                    Status = $"Scraping page {i + 1} of {totalPages}";
                    var mc = Regex.Matches(driver.PageSource, RegexUtility.IPv4AndPortWithSeperatorRegexString);
                    foreach (Match m in mc)
                    {
                        try
                        {
                            var proxy = new Proxy(m.Groups[1].Value + m.Groups[2].Value);
                            OnProxyScraped(proxy);
                        }
                        catch (Exception ex)
                        {
                            System.Diagnostics.Debug.WriteLine(ex); ;
                        }
                    }

                    if (pct != null) { await pct.PauseOrCancelIfRequested(); }

                    if (i < totalPages - 1)
                    {
                        var nextButton = wait.Until(extras.ExpectedConditions.ElementToBeClickable(By.XPath("//li[@class='arrow__right']/a")));
                        nextButton.Click();
                    }
                }
                Status = "Completed!";
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex);
            }
        });
    }
}

堆栈跟踪。

at OpenQA.Selenium.DriverService.Stop() 
at OpenQA.Selenium.DriverService.Dispose(Boolean disposing) 
at OpenQA.Selenium.Remote.DriverServiceCommandExecutor.Dispose(Boolean disposing) 
at OpenQA.Selenium.Remote.DriverServiceCommandExecutor.Execute(Command commandToExecute) 
at OpenQA.Selenium.Remote.RemoteWebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters) 
at OpenQA.Selenium.Remote.RemoteWebDriver.Dispose(Boolean disposing)
at OpenQA.Selenium.Remote.RemoteWebDriver.Quit() 
at HelperLib.ProxyLib.Scraping.ProxyScraperForm.stopButton_Click(Object sender, EventArgs e) in C:\Users\david\source\repos\HelperLib\HelperLib\ProxyLib\Scraping\ProxyScraperForm.cs:line 55 
at System.Windows.Forms.Control.OnClick(EventArgs e) 
at System.Windows.Forms.Button.OnClick(EventArgs e) 
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent) 
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) 
at System.Windows.Forms.Control.WndProc(Message& m) 
at System.Windows.Forms.ButtonBase.WndProc(Message& m) 
at System.Windows.Forms.Button.WndProc(Message& m) 
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) 
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) 
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) 
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData) 
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) 
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) 
at System.Windows.Forms.Application.RunDialog(Form form) 
at System.Windows.Forms.Form.ShowDialog(IWin32Window owner) 
at System.Windows.Forms.Form.ShowDialog() 
at HelperLib.ProxyLib.Testing.proxyTesterView.AddFromScraperToolStripMenuItem_Click(Object sender, EventArgs e) in C:\Users\david\source\repos\HelperLib\HelperLib\ProxyLib\Testing\ProxyTesterView.cs:line 127 
at System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e) 
at System.Windows.Forms.ToolStripMenuItem.OnClick(EventArgs e) 
at System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e) 
at System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e)
at System.Windows.Forms.ToolStripItem.FireEventInteractive(EventArgs e, ToolStripItemEventType met) 
at System.Windows.Forms.ToolStripItem.FireEvent(EventArgs e, ToolStripItemEventType met) 
at System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea) 
at System.Windows.Forms.ToolStripDropDown.OnMouseUp(MouseEventArgs mea)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) 
at System.Windows.Forms.Control.WndProc(Message& m) 
at System.Windows.Forms.ScrollableControl.WndProc(Message& m) 
at System.Windows.Forms.ToolStrip.WndProc(Message& m) 
at System.Windows.Forms.ToolStripDropDown.WndProc(Message& m) 
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) 
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) 
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) 
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData) 
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) 
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) 
at System.Windows.Forms.Application.Run(Form mainForm) 
at TestingApp.Program.Main() in C:\Users\david\source\repos\TestingApp\TestingApp\Program.cs:line 19

2 个答案:

答案 0 :(得分:0)

这是我的硒测试代码,希望它可以帮到你

var tasks = new List<Task>
        {
            new Task(PickUserFirefox)                
        };

        tasks.ForEach(
            task => task.Start()                
        );
        Task.WaitAll(tasks.ToArray());
    }

    private static void PickUserFirefox()
    {
        FirefoxTesting(StaticRandom.Instance.Next(1000,9999), "abcd");
    }

  private static void FirefoxTesting(int id, string fileIds)
    {
        System.Environment.SetEnvironmentVariable("webdriver.gecko.driver", @"D:\Work\Testing\SelenimDriver\geckodriver.exe");
        IWebDriver driver = new FirefoxDriver();
        driver.Navigate().GoToUrl(URL + id + "/" + fileIds);
        Thread.Sleep(1000);
         try
        {
            //Do something here
        }
        catch (Exception e)
        {
            //Error handle here
        }
        Thread.Sleep(1000);
        IWebElement btn = driver.FindElement(By.Id("btnSubmit"));
        btn.Click();
        Thread.Sleep(1000);
        //driver.Close();         
        driver.Quit();
    }

答案 1 :(得分:0)

通过使用ConcurrentDictionary并在lock语句中包装driver.Quit()来解决。

public partial class ProxyScraperForm : Form
{

    private BindingList<IProxyScraperSite> sites = new BindingList<IProxyScraperSite>();
    private ConcurrentDictionary<string, FirefoxDriver> activeDrivers = new ConcurrentDictionary<string, FirefoxDriver>();
    private object lockObj = new object();

    public BindingList<IProxyScraperSite> Sites { get { return this.sites; } }

    public ProxyScraperForm()
    {
        InitializeComponent();

        sites.Add(new ProxyScraperSiteUsProxyOrg());
        sites.Add(new ProxyScraperSiteFreeProxyListNet());
        sites.Add(new ProxyScraperSiteFreeProxyListsNet());
        sites.Add(new ProxyScraperSiteHideMyName());
        sites.Add(new ProxyScraperSiteHidester());
        scraperDataGridView.DataSource = sites;
    }

    private void scrapeButton_Click(object sender, EventArgs e)
    {
        foreach (var site in sites)
        {
            Task.Run(async () =>
            {
                var driver = SeleniumUtility.CreateDefaultFirefoxDriver();
                activeDrivers.TryAdd(site.SiteName, driver);
                await site.ScrapeAsync(driver);
                lock (lockObj)
                {
                    driver.Quit();
                }
                activeDrivers.TryRemove(site.SiteName, out driver);
            });
        }
    }

    private void stopButton_Click(object sender, EventArgs e)
    {
        foreach (var driver in activeDrivers)
        {
            lock (lockObj)
            {
                driver.Value.Quit();
            }
        }

        activeDrivers.Clear();

        foreach (var site in sites)
        {
            site.Status = "Idle";
        }
    }

    private void proxyScraperForm_FormClosing(object sender, FormClosingEventArgs e)
    {
        stopButton.PerformClick();
        this.DialogResult = DialogResult.Cancel;
    }
}