.NET WebAPI实现多chromedriver.exe实例并行执行的方案咨询
解决.NET WebAPI中ChromeDriver实例串行执行的问题
你的问题核心在于WebAPI端点的同步阻塞逻辑,以及ChromeDriver实例缺少独立运行配置,导致连续请求只能串行处理。以下是具体解决步骤:
1. 异步化WebAPI的进程调用逻辑
当前代码中process.WaitForExit()是同步阻塞方法,会占用请求线程直到进程结束,导致后续请求排队。改用异步版本的等待方法,释放线程池资源处理其他请求:
using (var process = new Process()) { // 使用Path.Combine避免路径拼接错误 process.StartInfo.FileName = Path.Combine(AppContext.BaseDirectory, "Exes", "WebRunner.exe"); process.StartInfo.Arguments = "https://testguild.com/HpSupport.html"; process.StartInfo.UseShellExecute = false; process.StartInfo.CreateNoWindow = true; process.StartInfo.RedirectStandardOutput = true; process.Start(); // 异步读取输出+异步等待进程退出,不阻塞请求线程 var outputTask = process.StandardOutput.ReadToEndAsync(); await process.WaitForExitAsync(); string result = await outputTask; await Console.Out.WriteLineAsync($"Result = {result}"); }
2. 为每个ChromeDriver实例配置独立运行环境
多个ChromeDriver实例共享默认配置会导致端口冲突、资源竞争,必须为每个实例分配独立的端口和用户数据目录:
修改WebRunner.exe的代码:
var path = Path.Combine(AppContext.BaseDirectory, "chromedriver.exe"); var guid = Guid.NewGuid().ToString().Replace("-", string.Empty); var newPath = path.Replace(".exe", $"{guid}.exe"); File.Copy(path, newPath); var chromeOptions = new ChromeOptions(); chromeOptions.AddArgument("--headless"); // 禁用共享内存,避免容器/低内存环境下的冲突 chromeOptions.AddArgument("--disable-dev-shm-usage"); // 为每个实例创建独立临时用户目录,隔离缓存和配置 var tempUserDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); chromeOptions.AddArgument($"--user-data-dir={tempUserDir}"); // 分配随机可用端口,避免调试端口冲突 chromeOptions.AddArgument($"--remote-debugging-port={GetAvailablePort()}"); driver = new ChromeDriver(newPath, chromeOptions); driver.Navigate().GoToUrl(args[0]); var d = driver.FindElement(By.XPath("/html/body")); // 程序退出时清理资源 try { driver.Quit(); File.Delete(newPath); Directory.Delete(tempUserDir, true); } catch (Exception ex) { Console.WriteLine($"清理资源失败: {ex.Message}"); } // 实现获取可用端口的辅助方法 private static int GetAvailablePort() { using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { socket.Bind(new IPEndPoint(IPAddress.Loopback, 0)); return ((IPEndPoint)socket.LocalEndPoint).Port; } }
3. 可选:调整ASP.NET线程池配置
如果并发请求量较大,可适当增加线程池最小线程数,确保有足够线程处理并行请求(在Program.cs中添加):
ThreadPool.SetMinThreads(50, 50); // 根据服务器硬件配置调整数值,不宜过大
完成以上修改后,连续调用WebAPI端点时,每个请求会触发独立的WebRunner.exe进程,每个进程启动专属的ChromeDriver实例,实现真正的并行执行。
内容的提问来源于stack exchange,提问作者Eru
相关产品推荐
相关产品推荐

