C# 即使使用HttpWebRequest C,XmlReader也会超时#
我看到了很多关于如何在XmlReader.Create方法上处理超时web异常的问题,并发现使用HttpWebRequest并为其设置超时属性将是最好的答案。但是超时错误仍然是主要问题C# 即使使用HttpWebRequest C,XmlReader也会超时#,c#,xml,web,C#,Xml,Web,我看到了很多关于如何在XmlReader.Create方法上处理超时web异常的问题,并发现使用HttpWebRequest并为其设置超时属性将是最好的答案。但是超时错误仍然是主要问题 在阅读此内容后,在@Icepickle的帮助下,我关闭了响应和读取器,并使用块作为响应和读取器: bool GetRssHtmlElement (string rssUrl, out HtmlDocument htmlReader) { try {
在阅读此内容后,在@Icepickle的帮助下,我关闭了响应和读取器,并使用块作为响应和读取器:
bool GetRssHtmlElement (string rssUrl, out HtmlDocument htmlReader)
{
try
{
#region Set Request
var request = (HttpWebRequest)WebRequest.Create(rssUrl.Replace("feed://", ""));
request.Proxy = null;
request.Timeout = 120000;
request.AllowAutoRedirect = true;
request.UseDefaultCredentials = true;
request.ServicePoint.MaxIdleTime = 120000;
request.MaximumAutomaticRedirections = 10;
request.CookieContainer = new CookieContainer ();
request.ServicePoint.ConnectionLeaseTimeout = 120000;
request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36";
#endregion
var response = (HttpWebResponse)request.GetResponse();
var encoding = Encoding.UTF8;
using (var reader = new StreamReader (response.GetResponseStream (), encoding))
{
var xmlSource = new XmlTextReader (reader);
xmlDoc = new XmlDocument ();
xmlDoc.Load (xmlSource);
reader.Close ();
}
response.Close();
return true;
}
catch (Exception ex)
{
//ErrorLogger.Log;
return false;
}
}
我现在有更少的“操作已超时”错误,但仍然会收到此错误。我不明白为什么会这样
更新: 首先,我从缓存中收集所有新闻来源(如CNN、BBC等),并为每个来源运行一个任务。大约有200个来源。运行方法是:
void Run()
{
var tempNewsSources = AllNewsSources.ToList();
NewsSourceTasks = new List<Task>();
foreach (var newsSource in tempNewsSources)
{
var tempNewsSource = newsSource;
NewsSourceTasks.Add(RunFlowsNew(tempNewsSource));
}
NewsSourceTasks.ForEach(n =>
{
n.Start();
Thread.Sleep(OneSecond);
});
}
更新3
我知道有些网站屏蔽了我的IP,所以我遇到了很多超时异常。有没有抓取web和新闻的最佳实践?关于
WebClient
及其异步任务的API:
try
{
using(var client = new WebClient())
{
var task = client.DownloadStringTaskAsync(Url);
if (task.Wait(300000))
{
var text = new StringReader(task.Result);
reader = new XmlTextReader(text);
return true;
}
}
return false;
}
catch (Exception ex)
{
return false;
}
如何使用WebClient
及其async任务
api:
try
{
using(var client = new WebClient())
{
var task = client.DownloadStringTaskAsync(Url);
if (task.Wait(300000))
{
var text = new StringReader(task.Result);
reader = new XmlTextReader(text);
return true;
}
}
return false;
}
catch (Exception ex)
{
return false;
}
首先我将getrselement方法更改为:
XmlDocument GetRssElement (string url)
{
try
{
var httpClient = new HttpClient();
#Region httpClientHeaders
httpClient.DefaultRequestHeaders.AcceptLanguage.Clear ();
httpClient.DefaultRequestHeaders.AcceptLanguage.Add (new StringWithQualityHeaderValue ("en-US"));
httpClient.DefaultRequestHeaders.AcceptLanguage.Add (new StringWithQualityHeaderValue ("en"));
httpClient.DefaultRequestHeaders.AcceptLanguage.Add (new StringWithQualityHeaderValue ("fa"));
httpClient.DefaultRequestHeaders.TryAddWithoutValidation ("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36");
httpClient.DefaultRequestHeaders.TryAddWithoutValidation ("Connection", "keep-alive");
httpClient.Timeout = TimeSpan.FromMinutes (1000);
var xmlDoc = new XmlDocument();
#EndRegion
try
{
var stream = httpClient.GetAsync(rssLinkRecord.Url.Replace("feed://", ""));
xmlDoc.LoadXml (stream.Result.Content.ReadAsStringAsync ().Result);
}
catch (XmlException) //if xml need encoding.
{
var wc = new WebClient();
var encoding = Encoding.GetEncoding("utf-8");
var data = wc.DownloadData(rssLinkRecord.Url.Replace("feed://", ""));
var gzip = new GZipStream(new MemoryStream(data), CompressionMode.Decompress);
var decompressed = new MemoryStream();
gzip.CopyTo (decompressed);
var str = encoding.GetString(decompressed.GetBuffer(), 0, (int) decompressed.Length);
xmlDoc = new XmlDocument ();
xmlDoc.LoadXml (str);
}
return xmlDoc;
}
catch (TaskCanceledException ex){}
catch (AggregateException aex){}
catch (XmlException xexi){}
catch (WebException wex){}
catch (Exception ex){}
}
我使用httpClient而不是请求和响应,并为其设置了适当的头。我使用了一个大的超时,因为如果一个请求在超时之前失败,这个组上的其他连接将失败。
我使用try-catch块来获取XmlException,并使用特定的编码来读取XML。最后,在这个方法中,我使用了不同的catch块,这样我就可以了解发生了哪种错误。
秒,我用
System.Net.ServicePointManager.DefaultConnectionLimit = 999999999;
这是在方法调用的第一行,用于删除.Net对连接的限制。
最后我更改了注册表中的一些设置,以删除windows服务器对连接的限制。首先我将GetrSelement方法更改为:
XmlDocument GetRssElement (string url)
{
try
{
var httpClient = new HttpClient();
#Region httpClientHeaders
httpClient.DefaultRequestHeaders.AcceptLanguage.Clear ();
httpClient.DefaultRequestHeaders.AcceptLanguage.Add (new StringWithQualityHeaderValue ("en-US"));
httpClient.DefaultRequestHeaders.AcceptLanguage.Add (new StringWithQualityHeaderValue ("en"));
httpClient.DefaultRequestHeaders.AcceptLanguage.Add (new StringWithQualityHeaderValue ("fa"));
httpClient.DefaultRequestHeaders.TryAddWithoutValidation ("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36");
httpClient.DefaultRequestHeaders.TryAddWithoutValidation ("Connection", "keep-alive");
httpClient.Timeout = TimeSpan.FromMinutes (1000);
var xmlDoc = new XmlDocument();
#EndRegion
try
{
var stream = httpClient.GetAsync(rssLinkRecord.Url.Replace("feed://", ""));
xmlDoc.LoadXml (stream.Result.Content.ReadAsStringAsync ().Result);
}
catch (XmlException) //if xml need encoding.
{
var wc = new WebClient();
var encoding = Encoding.GetEncoding("utf-8");
var data = wc.DownloadData(rssLinkRecord.Url.Replace("feed://", ""));
var gzip = new GZipStream(new MemoryStream(data), CompressionMode.Decompress);
var decompressed = new MemoryStream();
gzip.CopyTo (decompressed);
var str = encoding.GetString(decompressed.GetBuffer(), 0, (int) decompressed.Length);
xmlDoc = new XmlDocument ();
xmlDoc.LoadXml (str);
}
return xmlDoc;
}
catch (TaskCanceledException ex){}
catch (AggregateException aex){}
catch (XmlException xexi){}
catch (WebException wex){}
catch (Exception ex){}
}
我使用httpClient而不是请求和响应,并为其设置了适当的头。我使用了一个大的超时,因为如果一个请求在超时之前失败,这个组上的其他连接将失败。
我使用try-catch块来获取XmlException,并使用特定的编码来读取XML。最后,在这个方法中,我使用了不同的catch块,这样我就可以了解发生了哪种错误。
秒,我用
System.Net.ServicePointManager.DefaultConnectionLimit = 999999999;
这是在方法调用的第一行,用于删除.Net对连接的限制。
最后我更改了注册表中的一些设置,以消除windows服务器对连接的限制。有趣的是,RSS提要需要5分钟才能完成,您确定异常是超时异常吗?阅读此文后,我正在考虑将这些行添加到我的请求中<代码>request.ServicePoint.ConnectionLeaseTimeout=5000代码>request.ServicePoint.MaxIdleTime=5000
@Icepickle这不仅是超时异常,而且主要错误都与此有关。我将所有错误保存在日志文档中。您仍然没有处理WebException(捕获所有异常不会帮助您捕获WebException并关闭/处理相应的WebException.Response WebRequest)。您当前的示例代码也没有真正说明为什么需要这么多操作,以及如何调用当前代码。您是否有机会更新您的代码,以便我们更好地了解您正在尝试的内容,包括实际打开的并行请求数?另外,您可以检查的另一件事是:RSS提要需要5分钟才能完成,这很有趣,你确定该异常是超时异常吗?读完本文后,我正在考虑将这些行添加到我的请求中<代码>request.ServicePoint.ConnectionLeaseTimeout=5000代码>request.ServicePoint.MaxIdleTime=5000
@Icepickle这不仅是超时异常,而且主要错误都与此有关。我将所有错误保存在日志文档中。您仍然没有处理WebException(捕获所有异常不会帮助您捕获WebException并关闭/处理相应的WebException.Response WebRequest)。您当前的示例代码也没有真正说明为什么需要这么多操作,以及如何调用当前代码。您是否有机会更新您的代码,以便我们更好地了解您正在尝试的内容,包括实际打开的并行请求数?另外,您可以检查的另一件事是:谢谢,但如果我以文本形式读取Url,则无法在其中定义节点。我测试您的代码。但是仍然有超时web错误提示,但是如果我以文本形式读取Url,那么我无法在其中定义节点。我测试您的代码。但仍然存在超时web错误
System.Net.ServicePointManager.DefaultConnectionLimit = 999999999;