Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 即使使用HttpWebRequest C,XmlReader也会超时#_C#_Xml_Web - Fatal编程技术网

C# 即使使用HttpWebRequest C,XmlReader也会超时#

C# 即使使用HttpWebRequest C,XmlReader也会超时#,c#,xml,web,C#,Xml,Web,我看到了很多关于如何在XmlReader.Create方法上处理超时web异常的问题,并发现使用HttpWebRequest并为其设置超时属性将是最好的答案。但是超时错误仍然是主要问题 在阅读此内容后,在@Icepickle的帮助下,我关闭了响应和读取器,并使用块作为响应和读取器: bool GetRssHtmlElement (string rssUrl, out HtmlDocument htmlReader) { try {

我看到了很多关于如何在XmlReader.Create方法上处理超时web异常的问题,并发现使用HttpWebRequest并为其设置超时属性将是最好的答案。但是超时错误仍然是主要问题


在阅读此内容后,在@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;