C#中高效执行数千次HTTP请求检测网站存活的最优方案
优化C#批量检测网站存活的高效实现
针对你当前的实现,以下是几个关键优化点,能大幅提升数千次Web请求的执行速度:
核心优化方向
- 复用HttpClient与HttpClientHandler:这两个对象设计为可复用,频繁创建会导致Socket资源耗尽,严重拖慢性能。
- 异步并行+并发控制:同步遍历执行请求效率极低,改用异步并行同时限制并发数,避免系统资源过载。
- 轻量请求替代全内容获取:不需要下载整个页面内容,仅发送HEAD请求或检查响应状态码即可判断站点存活。
- 避免阻塞调用:全程使用
await替代.Result,防止线程阻塞浪费资源。
优化后的完整代码
// 全局复用的HttpClient实例 private static readonly HttpClient _httpClient; // 静态构造函数初始化HttpClient static YourClassName() { var handler = new HttpClientHandler { ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true // 注意:生产环境不建议全局禁用SSL验证,可根据实际情况调整 }; _httpClient = new HttpClient(handler) { // 设置合理的超时时间,避免等待过久 Timeout = TimeSpan.FromSeconds(10) }; } public static async Task CheckSitesAsync(string filePath) { // 读取所有站点链接 string[] sites = File.ReadAllLines(filePath); int totalSites = sites.Length; Console.WriteLine($"开始检测 {totalSites} 个站点..."); // 限制并发数,根据服务器性能调整(比如设置为50) var semaphore = new SemaphoreSlim(50); var tasks = new List<Task>(); foreach (string site in sites) { // 确保每个请求获取信号量后再执行 await semaphore.WaitAsync(); tasks.Add(Task.Run(async () => { try { await CheckSiteStatusAsync(site); } finally { // 释放信号量,允许下一个请求执行 semaphore.Release(); } })); } // 等待所有任务完成 await Task.WhenAll(tasks); Console.WriteLine($"\n检测完成,共 {totalSites} 个站点"); } private static async Task CheckSiteStatusAsync(string site) { try { // 使用HEAD请求替代GetStringAsync,仅获取响应头,节省带宽 using var response = await _httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, site)); // 只要状态码在2xx范围内就判定为正常 if (response.IsSuccessStatusCode) { Console.WriteLine($"Good - {site}"); } else { Console.WriteLine($"Bad - {site} (状态码: {(int)response.StatusCode})"); } } catch (Exception ex) { // 捕获所有请求异常,包括超时、无法连接等 Console.WriteLine($"Bad - {site} (错误: {ex.Message})"); } }
调用示例
// 在Main方法中调用 await CheckSitesAsync("你的站点文件路径");
额外说明
- 并发数调整:
SemaphoreSlim的参数可以根据你的网络环境和机器性能调整,过高的并发数可能导致本地网络拥堵或目标服务器限制,建议从30-50开始测试。 - 超时设置:根据实际需求调整
HttpClient.Timeout,避免单个请求阻塞过久影响整体速度。 - SSL验证:生产环境中请谨慎禁用SSL验证,若需要处理自定义证书,可在
ServerCertificateCustomValidationCallback中添加针对性逻辑。
内容的提问来源于stack exchange,提问作者RenardoSharp
相关产品推荐
相关产品推荐

