string url = "http://www.example.com/feed.xml";
var settings = new XmlReaderSettings();
settings.IgnoreComments = true;
settings.IgnoreProcessingInstructions = true;
settings.IgnoreWhitespace = true;
settings.XmlResolver = null;
settings.DtdProcessing = DtdProcessing.Parse;
settings.CheckCharacters = false;
var request = (HttpWebRequest)WebRequest.Create(url);
request.Timeout = 900000;
request.KeepAlive = true;
request.IfModifiedSince = lastModified;
var response = (HttpWebResponse)request.GetResponse();
Stream stream;
stream = response.GetResponseStream();
stream.ReadTimeout = 600000;
var xmlReader = XmlReader.Create(stream, settings);
while (!xmlReader.EOF)
{
...
当我在一个大型xml文件上尝试此操作时(下载速度也非常慢),我的azure Web应用程序会在几分钟后抛出一个空白页。
我在Azure的失败请求跟踪日志中看到了这一点:
ModuleName :DynamicCompressionModule
通知:SEND_RESPONSE
HttpStatus :500
HttpReason :内部服务器错误
HttpSubStatus :19
ErrorCode :尝试对不存在的网络连接进行操作。 (0x800704cd)
正如你所看到的,我一直在玩“超时设置”。 还尝试捕获所有异常,但它没有捕获任何异常。
此外,在我的计算机上本地调试Web应用程序时,这没有问题。可能是我办公室的互联网连接比Azure更好,导致xml文件快速读取而没有任何问题。
任何可能的解决方法? 编辑:我想继续流式传输XML文件(我避免下载整个文件,因为用户可以选择只读取Feed的前N个条目)。如果无法避免上述问题,我很高兴有人可以帮助我至少向用户显示有意义的信息,而不是空白页。
答案 0 :(得分:2)
尝试使用WebClient类获取xml文件。
string xmlAsString;
using (var xmlWebClient = new WebClient())
{
xmlWebClient.Encoding = Encoding.UTF8;
xmlAsString = xmlWebClient.DownloadString(url);
}
XmlDocument currentXml = new XmlDocument();
currentXml.Load(xmlAsString);
答案 1 :(得分:1)
你可以使用
string url = "http://www.example.com/feed.xml";
using(var reader = XmlReader.Create(url){
它应该支持url(参见here)。然后可以通过yield return x
使用流媒体。这可能是您最好的选择,因为您可以让本机组件按照自己的方式处理流式传输。您甚至可以通过ReadValueChunk方法对文件进行分块。
另一个考虑因素,也就是我猜测的问题是Azure实例的大小。除非在最高层,否则Azure实例的内存量非常小。
我也没有看到你处理任何你的流,这也可能导致内存泄漏和内存使用过多。
并且考虑到它适用于您的计算机,并且大多数个人计算机至少与A3实例(顶层以下一层)一样强大,并且具有用于清理本地内存泄漏的IDE,并且它似乎可行天蓝色的实例可能是个问题。
一种可能的解决方案是使用文件流。在一定大小之后,内存流和文件流非常相似。一个使用文件系统,而另一个使用sys文件(IIRC pagefile.sys),因此转换为文件流对性能影响不大,缺点是必须在完成后清理文件。但是,当美元成为考虑因素时,磁盘流在天蓝色的世界中会更便宜。
答案 2 :(得分:0)
试试这个
static IEnumerable<XElement> StreamCustomerItem(string uri)
{
using (XmlReader reader = XmlReader.Create(uri))
{
XElement name = null;
XElement item = null;
reader.MoveToContent();
// Parse the file, save header information when encountered, and yield the
// Item XElement objects as they are created.
// loop through Customer elements
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element
&& reader.Name == "Customer")
{
// move to Name element
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element &&
reader.Name == "Name")
{
name = XElement.ReadFrom(reader) as XElement;
break;
}
}
// loop through Item elements
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.EndElement)
break;
if (reader.NodeType == XmlNodeType.Element
&& reader.Name == "Item")
{
item = XElement.ReadFrom(reader) as XElement;
if (item != null)
{
XElement tempRoot = new XElement("Root",
new XElement(name)
);
tempRoot.Add(item);
yield return item;
}
}
}
}
}
}
}
static void Main(string[] args)
{
XStreamingElement root = new XStreamingElement("Root",
from el in StreamCustomerItem("Source.xml")
select new XElement("Item",
new XElement("Customer", (string)el.Parent.Element("Name")),
new XElement(el.Element("Key"))
)
);
root.Save("Test.xml");
Console.WriteLine(File.ReadAllText("Test.xml"));
}
基于以下XML
<?xml version="1.0" encoding="utf-8"?>
<Root>
<Item>
<Customer>A. Datum Corporation</Customer>
<Key>0001</Key>
</Item>
<Item>
<Customer>A. Datum Corporation</Customer>
<Key>0002</Key>
</Item>
<Item>
<Customer>A. Datum Corporation</Customer>
<Key>0003</Key>
</Item>
<Item>
<Customer>A. Datum Corporation</Customer>
<Key>0004</Key>
</Item>
<Item>
<Customer>Fabrikam, Inc.</Customer>
<Key>0005</Key>
</Item>
<Item>
<Customer>Fabrikam, Inc.</Customer>
<Key>0006</Key>
</Item>
<Item>
<Customer>Fabrikam, Inc.</Customer>
<Key>0007</Key>
</Item>
<Item>
<Customer>Fabrikam, Inc.</Customer>
<Key>0008</Key>
</Item>
<Item>
<Customer>Southridge Video</Customer>
<Key>0009</Key>
</Item>
<Item>
<Customer>Southridge Video</Customer>
<Key>0010</Key>
</Item>
</Root>