You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

IIS部署Selenium测试时ChromeDriver意外生成多实例问题如何解决

问题排查与解决方案

问题复现背景

我是Selenium新手,还在学习阶段,如果问题表述不够专业还请谅解。
我们尝试通过IIS在指定机器上运行Selenium测试。
本地运行代码时一切正常,但发布到目标机器后,仅执行一次任务就会在任务管理器中出现2个ChromeDriver实例,运行状态极不稳定:有时会关闭其中一个实例,有时两个都不关闭,偶尔也会出现两个实例都正常关闭、程序运行无误的情况,暂时无法定位造成该不稳定问题的原因。
任务管理器截图

原运行代码

private IWebDriver _driver;

[Route("/Test_SignIn")]
public IActionResult Test_SignIn(string environment = "development")
{
    string response = "Failed";

    try
    {
        string outPutDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
        _driver = new ChromeDriver(outPutDirectory);

        if (environment == "production")
        {
            _driver.Navigate().GoToUrl(productionUrl);
        }
        else
        {
            _driver.Navigate().GoToUrl(developmentUrl);
        }

        By userNameFieldLocator = By.Id("AccountUserName");
        WebDriverWait wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(30));
        wait.Until(ExpectedConditions.ElementIsVisible(userNameFieldLocator));
        _waitForLoaderToFinish();
        IWebElement userNameField = _driver.FindElement(userNameFieldLocator);
        IWebElement passwordField = _driver.FindElement(By.Id("AccountPassword"));
        IWebElement signInButton = _driver.FindElement(By.XPath("//button[contains(text(), 'Sign In')]"));
        userNameField.SendKeys(_username);
        passwordField.SendKeys(_password);
        signInButton.Click();
        By dashboardLocator = By.Id("portalBanner_EmployeeName");

        wait.Until(ExpectedConditions.ElementIsVisible(dashboardLocator));

        IWebElement dashboard = _driver.FindElement(dashboardLocator);
        response = "Success";
    }
    catch (Exception ex)
    {
        response = ex.Message;
    }

    _driver.Close();
    _driver.Quit();

    return Json(response);
}

private string _waitForLoaderToFinish()
{
    try
    {
        new WebDriverWait(_driver, TimeSpan.FromSeconds(30)).Until(ExpectedConditions.InvisibilityOfElementLocated(By.Id("loader-wrapper")));

        return null;
    }
    catch (TimeoutException e)
    {
        return $"{e.Message}";
    }
}

修复方案

  • 移除类级别全局_driver变量,改为方法内局部变量,避免IIS并发请求下变量被覆盖导致旧实例失去引用无法释放。
  • 将driver释放逻辑移入finally块,确保无论请求执行成功还是抛出异常,都能正常回收进程。
  • 新增Chrome启动适配参数,适配服务器无UI运行场景,减少进程异常概率。
  • 新增Dispose调用,主动释放非托管资源。

修复后核心代码示例

[Route("/Test_SignIn")]
public IActionResult Test_SignIn(string environment = "development")
{
    string response = "Failed";
    IWebDriver driver = null;
    try
    {
        string outPutDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
        // 配置Chrome启动参数
        var options = new ChromeOptions();
        options.AddArgument("--headless=new");
        options.AddArgument("--no-sandbox");
        options.AddArgument("--disable-dev-shm-usage");
        options.AddArgument("--disable-gpu");
        options.LeaveBrowserRunning = false;
        
        driver = new ChromeDriver(outPutDirectory, options);

        if (environment == "production")
        {
            driver.Navigate().GoToUrl(productionUrl);
        }
        else
        {
            driver.Navigate().GoToUrl(developmentUrl);
        }

        By userNameFieldLocator = By.Id("AccountUserName");
        WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
        wait.Until(ExpectedConditions.ElementIsVisible(userNameFieldLocator));
        _waitForLoaderToFinish(driver);
        IWebElement userNameField = driver.FindElement(userNameFieldLocator);
        IWebElement passwordField = driver.FindElement(By.Id("AccountPassword"));
        IWebElement signInButton = driver.FindElement(By.XPath("//button[contains(text(), 'Sign In')]"));
        userNameField.SendKeys(_username);
        passwordField.SendKeys(_password);
        signInButton.Click();
        By dashboardLocator = By.Id("portalBanner_EmployeeName");

        wait.Until(ExpectedConditions.ElementIsVisible(dashboardLocator));

        IWebElement dashboard = driver.FindElement(dashboardLocator);
        response = "Success";
    }
    catch (Exception ex)
    {
        response = ex.Message;
    }
    finally
    {
        if (driver != null)
        {
            driver.Close();
            driver.Quit();
            driver.Dispose();
        }
    }
    return Json(response);
}

// _waitForLoaderToFinish同步修改为接收driver参数,不依赖全局变量
private string _waitForLoaderToFinish(IWebDriver driver)
{
    try
    {
        new WebDriverWait(driver, TimeSpan.FromSeconds(30)).Until(ExpectedConditions.InvisibilityOfElementLocated(By.Id("loader-wrapper")));
        return null;
    }
    catch (TimeoutException e)
    {
        return $"{e.Message}";
    }
}

额外注意事项

  • 确保IIS运行站点的应用程序池身份有足够的权限访问Chrome和ChromeDriver的执行文件,权限不足也会导致进程启动异常无法受控。
  • 确保服务器上安装的Chrome版本和使用的ChromeDriver版本完全匹配,版本不兼容会出现各种非预期异常。

内容的提问来源于stack exchange,提问作者Ryan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 20:36:03