c# - 在并行任务期间跟踪失效的 WebDriver 实例

标签 c# webdriver task-parallel-library thread-local

我看到一些使用 Selenium WebDriver 运行并行嵌套循环 Web 压力测试的死实例怪异现象,简单的例子是,比如说,点击 300 个唯一页面,每个页面有 100 次展示。

我“成功”使用 ThreadLocal<FirefoxWebDriver> 获取 4 - 8 个 WebDriver 实例每个任务线程隔离它们,并在 ParallelOptions 实例上使用 MaxDegreeOfParallelism 来限制线程。我仅对外部循环(页面集合)进行分区和并行化,并检查 .IsValueCreated关于ThreadLocal<>容器内部每个分区的“长时间运行任务”方法的开始。为了便于稍后清理,我将每个新实例添加到以线程 ID 为键控的 ConcurrentDictionary 中。

无论我使用什么并行化或分区策略,WebDriver 实例偶尔都会执行以下操作之一:

  • 启动但不显示网址或进行展示
  • 启动,运行任意数量的展示次数,然后在某个时刻闲置

当其中任何一种情况发生时,并行循环最终似乎会注意到线程没有执行任何操作,并且它会生成一个新分区。如果 n 是允许的线程数,则这会导致 n 个高效线程仅在大约 50-60% 的时间内出现。

最后清理工作仍然正常;可能有 2n 个或更多打开的浏览器,但高效和低效的浏览器都会被清理。

有没有办法监视这些无用的 WebDriver 实例,并且 a) 立即清除它们,再加上 b) 让并行循环立即替换任务段,而不是像现在那样滞后几分钟?

最佳答案

我也遇到了类似的问题。事实证明,WebDriver 没有查找开放端口的最佳方法。如上所述here它会在端口上获得系统范围的锁定,找到开放的端口,然后启动实例。这可能会导致您尝试启动的其他实例缺乏端口。

我通过直接在ThreadLocal<IWebDriver>的委托(delegate)中指定一个随机端口号来解决这个问题。像这样:

        var ports = new List<int>();
        var rand = new Random((int)DateTime.Now.Ticks & 0x0000FFFF);

        var driver = new ThreadLocal<IWebDriver>(() =>
        {
            var profile = new FirefoxProfile();
            var port = rand.Next(50) + 7050;
            while(ports.Contains(port) && ports.Count != 50) port = rand.Next(50) + 7050;
            profile.Port = port;
            ports.Add(port);
            return new FirefoxDriver(profile);
        });

这对我来说效果相当一致,尽管如果您最终使用了列表中 Unresolved 所有 50 个,则会出现问题。

关于c# - 在并行任务期间跟踪失效的 WebDriver 实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10327095/

相关文章:

c# - 使用特定调色板在 C# 中实现 Floyd-Steinberg 抖动

c# - 更新 ASP .Net MVC 中的记录

python - Selenium 和新标签

node.js - 如何使用 Webdriver 控制 Firefox 扩展的侧边栏

c# - 如何在C#和VB.NET中模拟C++ friend ?

c# - 处理带密码的 Excel 工作表

javascript - WebDriver:更改事件未触发

c# - 异步调用带有输出参数的方法

c# - 用锁包装任务不是很有用吗?

c# - 将多个 TransformBlock 链接到单个 BatchBlock TPL