XslCompiledTransform 与 XslTransform 以及 OOM 怎么样?
所以有一段时间我一直在使用 XslCompiledTransform,因为微软告诉我我需要使用 XslTransform,因为 XslTransform 已被弃用。 最近我不得不将它与具有近 100,000 行的转换一起使用(当然是生成的 xsl)。 当我使用我的应用程序时,我惊讶地发现 OOM 弹出。 无论我做了什么 - OOM 就是我得到的一切...为了咯咯笑,我回到了 XslTransform...相同的代码将 XslCompiledTransform 更改为 XslTransform 并且它工作正常...
任何人都可以告诉我如何解决 OOM - 是XslCompiledTransform 上有一些“开关”吗? 我不知道你将如何能够复制确切的问题,但如果有人有任何答案,他们将非常感激。
谢谢 - 下面的代码:
有效:
XslTransform myXslTransform = new XslTransform();
myXslTransform.Load(xslWith100ThousandLines);
MemoryStream m = new MemoryStream();
myXslTransform.Transform(myXPathDocument, null, m);
m.Flush();
m.Close();
因 OOM 失败
XslCompiledTransform cxslt = new XslCompiledTransform();
cxslt.Load(xslWith100ThousandLines);
MemoryStream m = new MemoryStream();
cxslt.Transform(myXPathDocument, null, m);
m.Flush();
m.Close();
So for a while I've been using XslCompiledTransform because that's what Microsoft tells me I need to use as XslTransform is deprecated. Recently I had to use it with a transform that has nearly 100,000 lines (generated xsl - of course). When I used my application I was shocked to see an OOM pop up. No matter what I did - OOM is all I get... For giggles I went back to XslTransform... Same exact code changing XslCompiledTransform to XslTransform and it works fine...
Can anyone tell me how to work around the OOM - is there some 'swtich' on XslCompiledTransform? I don't know how you will be able to replicate the exact problem, but if anyone has any answers they're much appreciated.
Thanks - code below:
Works:
XslTransform myXslTransform = new XslTransform();
myXslTransform.Load(xslWith100ThousandLines);
MemoryStream m = new MemoryStream();
myXslTransform.Transform(myXPathDocument, null, m);
m.Flush();
m.Close();
Fails with OOM
XslCompiledTransform cxslt = new XslCompiledTransform();
cxslt.Load(xslWith100ThousandLines);
MemoryStream m = new MemoryStream();
cxslt.Transform(myXPathDocument, null, m);
m.Flush();
m.Close();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
好吧,现在我想,也许这更像是“微软就是微软”...凭直觉,我将目标平台改回“任何 CPU”,关闭了所有打开的 Visual Studio 实例并重新打开了我的项目...然后我清理、重新编译和重新运行,我再次遇到 OOM...
然后我将目标平台设置回 x86 和低版本,发现不再有 OOM! 我遇到过很多像这样的 x64 相关问题,将来我一定会将它们包含在任何帖子中...通常是由于 x64...
奇怪...但问题已“解决”。 ..:S
ok, so now i think, maybe this is more 'microsoft being microsoft'... on a hunch i changed the target platform back to "Any CPU", closed ALL my visual studio instances open and reopened my project... i then cleaned, recompiled, and reran and i am again getting the OOM...
i then set the target platform back to x86 and low and behold no more OOM! i've had a lot of x64 related issues like this and in the future i will be sure to include them in any postings... more often than not it's due to x64...
odd... but problem 'solved'... :S
起初,我认为您应该将其作为错误在 Microsoft Connect 上归档,但现在想一想,这并不是真正的错误。 对于这么大的 XSL 文档,您很可能会遇到 OOM 异常。
我仍然会将其发布在那里,只是因为我不希望新的 XslCompiledTransform 会在 XslTransform 不会失败时失败。
如果结果文档很大,是否可以将文档保存到磁盘上的临时文件流中,然后在处理文档时使用它?
At first, I thought that you should file it at Microsoft Connect as a bug, but thinking about it now, it's not really a bug. With an XSL document that large, you more than likely did hit an OOM exception.
I would still post it there, just because I wouldn't expect the new XslCompiledTransform to fail when the XslTransform doesn't.
If the result document is large, maybe save the document to a temp FileStream on disk and then work from that while processing the document?
令人惊讶的是,我的印象是旧的 XslTransform 只是链接到新的 XslCompiledTransoform。
第一次使用就出现OOM了吗? 请记住,任何已编译的内容(XslCompiledTransoform、XmlSerializer、带有 RegexOptions.Compiled 的 Regex)都会将程序集加载到您的 AppDomain 中。 程序集一旦添加到 AppDomain 中就无法删除。 这里有几个选项:
如果您在设计时生成该 XSLT 文件,那么检索由它创建的程序集并将其与您的应用程序(而不是 XSLT)打包在一起可能是值得的。 如果是在运行时,则必须使用上面的选项 (1)。
Suprising, I was under the impression that the old XslTransform just chained to the new XslCompiledTransoform.
Did you get the OOM on the first usage? Remember, anything compiled (XslCompiledTransoform, XmlSerializer, Regex with RegexOptions.Compiled) loads assemblies into your AppDomain. Assemblies can not be removed once added to an AppDomain. You have a few options here:
If you are generating that XSLT file at design time, it may be worth your while retrieving the assembly created by it and packaging it with your application instead of the XSLT. If it is at runtime, you will have to go with option (1) above.
好吧... Windows 世界中的编程始终是一个谜...
我感谢你们俩的回答,但是今天 - 在尝试复制问题时(消失了大约 14 小时后),问题已经完全消失了
...我做的唯一不同的事情是将编译器设置为 x86 而不是 x64,现在代码的工作原理与我开始时的预期完全一样,我比以往任何时候都更加困惑......
只是为了让每个人都知道我不是疯狂的是,这是连续两次运行的任务管理器快照:
我不是确定如何或为什么......但就是这样......
well... programming in the windows world is always a mystery...
i thank you both for your answers however today - while trying to replicate the problem (after being gone for around 14 hrs) the issue has disappeared entirely...
the only thing i did differently was to set the compiler to be x86 instead of x64 and now the code works exactly as i'd have expected to begin with and i am left more confused than ever...
just so everyone knows i'm not crazy, here's the task manager snap from two successive runs:
i'm not sure how or why... but there's that...