C# 正在检查IIS Express上多个页面的HTTP状态:使IIS Express崩溃
我正在编写一个简单的C控制台应用程序,它的主要任务是,当给定一组URL时,ping这些URL并报告是否返回了HTTP200OK结果。现实生活中的数据集在20000个URL的范围内进行测试,以验证大规模编辑没有破坏任何页面 当前,检查响应的代码如下所示:C# 正在检查IIS Express上多个页面的HTTP状态:使IIS Express崩溃,c#,iis,optimization,iis-express,C#,Iis,Optimization,Iis Express,我正在编写一个简单的C控制台应用程序,它的主要任务是,当给定一组URL时,ping这些URL并报告是否返回了HTTP200OK结果。现实生活中的数据集在20000个URL的范围内进行测试,以验证大规模编辑没有破坏任何页面 当前,检查响应的代码如下所示: public UrlTestResult TestUrl(string url) { if (string.IsNullOrWhiteSpace(url)) { throw new ArgumentNullExce
public UrlTestResult TestUrl(string url)
{
if (string.IsNullOrWhiteSpace(url))
{
throw new ArgumentNullException("url");
}
using (var client = new HttpClient())
{
try
{
Task<HttpResponseMessage> message = client.GetAsync(url);
if (message == null || message.Result == null)
{
return new FailedUrlTestResult(url, "No response was returned.");
}
if (message.Result.StatusCode == HttpStatusCode.OK)
{
return new SuccessfulUrlTestResult(url);
}
return new FailedUrlTestResult(url, "{0}: {1}".Format((int)message.Result.StatusCode, message.Result.ReasonPhrase));
}
catch (Exception ex)
{
return new FailedUrlTestResult(url, "An exception occurred: " + ex);
}
}
}
public sealed class UrlTester : IUrlTester
{
private readonly HttpClient httpClient = new HttpClient();
public UrlTestResult TestUrl(string url)
{
if (string.IsNullOrWhiteSpace(url))
{
throw new ArgumentNullException("url");
}
try
{
Task<HttpResponseMessage> message = httpClient.GetAsync(url);
if (message == null || message.Result == null)
{
return new FailedUrlTestResult(url, "No response was returned.");
}
if (message.Result.StatusCode == HttpStatusCode.OK)
{
return new SuccessfulUrlTestResult(url);
}
return new FailedUrlTestResult(url, "{0}: {1}".FormatCurrentCulture((int)message.Result.StatusCode, message.Result.ReasonPhrase));
}
catch (Exception ex)
{
return new FailedUrlTestResult(url, "An exception occurred: " + ex);
}
}
public void Dispose()
{
if (httpClient != null)
{
httpClient.Dispose();
}
}
}
此代码适用于较小的数据集。即使我使用Parallel.ForEach而不是普通的ForEach来迭代URL集合,它的行为也很好。但是,在运行几分钟左右后,在解析20000数据集时,承载localhost的IIS Express将崩溃
我猜我的选择是:
用完IIS,看看是否有效
限制请求的数量,让IIS Express有机会呼吸。这里的技巧是限制多少
在更小的块中测试URL,类似于第二个选项
我想知道的是:
有没有比HttpClient更便宜的方法ping URL并获取其HTTP响应?
我是否应该考虑IIS或IIS Express的任何配置选项?
编辑:我发现IIS Express似乎只是内存不足。图中是发生碰撞的实例:
这意味着IIS Express保留了显然不需要的内存,因为一旦请求结束,我就不再关心它了。不过,我不知道这是否有助于解决我的问题。我只是改为使用IIS运行localhost,而不是IIS Express。内存使用量大致相同,但在应用程序运行的十分钟内,它从未在任何时候崩溃。我还采纳了Gabi的意见/建议,并让HttpClient只实例化一次,而不是每次测试实例化一次。最后的代码如下所示:
public UrlTestResult TestUrl(string url)
{
if (string.IsNullOrWhiteSpace(url))
{
throw new ArgumentNullException("url");
}
using (var client = new HttpClient())
{
try
{
Task<HttpResponseMessage> message = client.GetAsync(url);
if (message == null || message.Result == null)
{
return new FailedUrlTestResult(url, "No response was returned.");
}
if (message.Result.StatusCode == HttpStatusCode.OK)
{
return new SuccessfulUrlTestResult(url);
}
return new FailedUrlTestResult(url, "{0}: {1}".Format((int)message.Result.StatusCode, message.Result.ReasonPhrase));
}
catch (Exception ex)
{
return new FailedUrlTestResult(url, "An exception occurred: " + ex);
}
}
}
public sealed class UrlTester : IUrlTester
{
private readonly HttpClient httpClient = new HttpClient();
public UrlTestResult TestUrl(string url)
{
if (string.IsNullOrWhiteSpace(url))
{
throw new ArgumentNullException("url");
}
try
{
Task<HttpResponseMessage> message = httpClient.GetAsync(url);
if (message == null || message.Result == null)
{
return new FailedUrlTestResult(url, "No response was returned.");
}
if (message.Result.StatusCode == HttpStatusCode.OK)
{
return new SuccessfulUrlTestResult(url);
}
return new FailedUrlTestResult(url, "{0}: {1}".FormatCurrentCulture((int)message.Result.StatusCode, message.Result.ReasonPhrase));
}
catch (Exception ex)
{
return new FailedUrlTestResult(url, "An exception occurred: " + ex);
}
}
public void Dispose()
{
if (httpClient != null)
{
httpClient.Dispose();
}
}
}
这个类的调用者利用C的using语句来确保HttpClient实例被正确处理。您是否直接调用Parallel.ForEach中的TestUrl?HttpClient类的设计是为了能够安全地重用实例。请参阅此处的备注部分:因此,您不应根据url实例化HttpClient实例。@Gabi我已将代码更新为仅使用单个HttpClient实例。