如何从 URL 读取 Windows 应用程序中的大量 xml 文件(从 Windows 应用程序到服务器的多个请求)c#
Posted
技术标签:
【中文标题】如何从 URL 读取 Windows 应用程序中的大量 xml 文件(从 Windows 应用程序到服务器的多个请求)c#【英文标题】:How to read numerous xml files from windows appication from URL (multiple requests to server from windows app) c# 【发布时间】:2015-10-04 01:45:41 【问题描述】:我有一个 Windows 表单,用户可以在其中下载选定日期期间的所有货币汇率。我现在有这个:
for (DateTime d = fromDatePicker.Value.Date; d <= toDatePicker.Value.Date; d.AddDays(1))
if (d.DayOfWeek == DayOfWeek.Saturday || d.DayOfWeek == DayOfWeek.Sunday)
return;
string url = "http://cbar.az/currencies/" + d.ToString("dd.MM.yyyy", CultureInfo.InvariantCulture) + ".xml";
XmlDocument doc = new XmlDocument();
doc.Load(url);
//other stuff
根据日期,URL 格式如下所示:http://cbar.az/currencies/15.07.2015.xml 例如,如果我选择两周时间,它会获得两天的费率,然后跳过两天等等。抛出一个错误甚至没有到达末尾期间:
远程服务器返回错误(503)服务器不可用
我猜这是一种针对多个客户端请求的服务器端保护,但不知道如何解决这个问题。
如果我选择 2 或 3 天的时间段,它不会引发错误。但在这里它也可能不会获得所有日期的费率。
感谢您的帮助。谢谢。
这是我的全部代码:
for (DateTime d = fromDatePicker.Value.Date; d <= toDatePicker.Value.Date; d.AddDays(1))
if (d.DayOfWeek == DayOfWeek.Saturday || d.DayOfWeek == DayOfWeek.Sunday)
continue;
string url = "http://cbar.az/currencies/" + d.ToString("dd.MM.yyyy", CultureInfo.InvariantCulture) + ".xml";
#region read rates for the date to the DataTable
XmlDocument doc = new XmlDocument();
doc.Load(url);
XmlElement root = doc.DocumentElement;
XmlNodeList nodes = root.SelectNodes("//ValCurs/ValType");
DataTable tempRates = new DataTable();
foreach (XmlNode node in nodes)
if (node.Attributes["Type"].Value == "Xarici valyutalar")
//create temp table and load new rates
tempRates.Clear();
tempRates.Columns.Add("Code");
tempRates.Columns.Add("Nominal");
tempRates.Columns.Add("Name");
tempRates.Columns.Add("Value");
foreach (XmlNode currency in node.ChildNodes)
DataRow dr = tempRates.NewRow();
dr["Code"] = currency.Attributes["Code"].Value;
foreach (XmlNode currencyDetailsNode in currency.ChildNodes)
dr[currencyDetailsNode.Name] = currencyDetailsNode.InnerText;
tempRates.Rows.Add(dr);
#endregion
DAL dal = new DAL();
dal.ClearCurrentRates(d);
//insert new values
foreach (DataRow currencyRow in StaticValues.dataSet.Tables["Currencies"].Rows)
if (currencyRow["Code"].ToString() == "AZN")
#region Insert the row for AZN
try
SqlParameter[] pars = new SqlParameter[3];
pars[0] = new SqlParameter("@Date", SqlDbType.Date);
pars[0].Value = d.ToShortDateString();
pars[1] = new SqlParameter("@CurrencyID", SqlDbType.Int);
pars[1].Value = currencyRow["ID"].ToString();
pars[2] = new SqlParameter("@Rate", SqlDbType.Decimal);
pars[2].Value = 1.0000;
dal.InsertData("CurrencyRates", pars);
catch (Exception ex)
StaticValues.WriteEventLogXML(ex, this.Text);
switch (StaticValues.user.Language)
case "English":
MessageBox.Show("Database error", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case "Russian":
MessageBox.Show("Ошибка базы данных", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case "Azeri":
MessageBox.Show("Məlumat bazası səhvi", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
default:
break;
#endregion
continue;
foreach (DataRow tempRow in tempRates.Rows)
if (tempRow["Code"].ToString() == currencyRow["Code"].ToString())
#region Insert the row
try
SqlParameter[] pars = new SqlParameter[3];
pars[0] = new SqlParameter("@Date", SqlDbType.Date);
pars[0].Value = d.ToShortDateString();
pars[1] = new SqlParameter("@CurrencyID", SqlDbType.Int);
pars[1].Value = currencyRow["ID"].ToString();
pars[2] = new SqlParameter("@Rate", SqlDbType.Decimal);
pars[2].Value = decimal.Parse(tempRow["Value"].ToString());
dal.InsertData("CurrencyRates", pars);
break;
catch (Exception ex)
StaticValues.WriteEventLogXML(ex, this.Text);
switch (StaticValues.user.Language)
case "English":
MessageBox.Show("Database error", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case "Russian":
MessageBox.Show("Ошибка базы данных", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
case "Azeri":
MessageBox.Show("Məlumat bazası səhvi", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
default:
break;
break;
#endregion
d = d.AddDays(1);
Thread.Sleep(1000);
【问题讨论】:
for (DateTime d = new DateTime(2015, 07, 01); d <= new DateTime(2015, 07, 15); d.AddDays(1))
我的控制台解决方案没有错误!
这不是关于迭代日期,这个效果很好。我想这是关于对服务器的多个请求。据我所知,有些服务器会因为潜在的服务器攻击而拒绝多个请求。
【参考方案1】:
你的东西完全错了。
方法 AddDays(x) 不会更新你的“d”变量,所以构造
for (DateTime d = fromDatePicker.Value.Date; d <= toDatePicker.Value.Date; d.AddDays(1))
产生无限循环
2.
if (d.DayOfWeek == DayOfWeek.Saturday || d.DayOfWeek == DayOfWeek.Sunday)
return;
完全退出循环。
-
似乎远程服务器在短时间内处理了许多请求时存在某种性能问题。它可以通过请求之间的一些暂停来解决(例如:Thread.Sleep(2000) - 两秒暂停)
因此,您的代码将如下所示:
for (DateTime d = fromDatePicker.Value.Date; d <= toDatePicker.Value.Date; d = d.AddDays(1))
if (d.DayOfWeek == DayOfWeek.Saturday || d.DayOfWeek == DayOfWeek.Sunday)
continue;
string url = "http://cbar.az/currencies/" + d.ToString("dd.MM.yyyy", CultureInfo.InvariantCulture) + ".xml";
XmlDocument doc = new XmlDocument();
doc.Load(url);
Thread.Sleep(2000);
【讨论】:
paYa,非常感谢您的回答。我将逐点评论它们: 1. 我在 'for 语句的末尾有这个:d = d.AddDays(1); 2. 那是我的错!谢谢指点。 3. 我已经添加了那个。 2-3 天它工作正常,但如果我选择一周,它就会变得毫无反应。我在“for”语句的末尾添加了 Thread.Sleep(2000) 行。是不是我又做错了什么? 无响应是什么意思?多久? Thread.Sleep 将线程的整个执行冻结 n 毫秒(除非您执行此异步操作)。所以,如果你有一周的时间,那将是大约。 5x(不含周末)2000 ms + 5 x 处理请求的时间。整个操作大约需要 20 秒。你能提供你当前的代码sn-p吗? 是的,我的计算方式完全相同。 2 秒 x 5 天 = 10 秒。但整个应用程序冻结。我的笔记本电脑一直在运行该应用程序,但超过 1 小时没有响应。我已经更新了我的第一篇文章。请查看我的整个代码以了解那里的程序。 您的“for”语句仍然很糟糕,并陷入无限循环。只需从 for 语句的底部删除“d = d.AddDays(1)”并将第一行更改为“for (DateTime d = fromDatePicker.Value.Date;d 仅供参考,您的构造问题是,当找到第一个周末时,“继续”关键字一次中断迭代并再次跳转到循环的开始,所以你的行"d = d.AddDays(1)" 永远不会被调用,因为它位于底部。以上是关于如何从 URL 读取 Windows 应用程序中的大量 xml 文件(从 Windows 应用程序到服务器的多个请求)c#的主要内容,如果未能解决你的问题,请参考以下文章
如何从 C++/Qt 中的 .exe 和 .dlls 中读取图标(在 Windows 上)?