如何在 Transform 上设置超时
How to put a timeout on Transform
XslCompiledTransform.Transform
在某些情况下(堆栈溢出、无限循环等)会挂起。这是一个依赖于数据(输入)的错误,所以我无法完全控制它的发生。如果发生这种情况,我希望得到优雅的通知,但我不希望它破坏我的应用程序进程以及用户输入输入的 GUI,这可能是 "valid" 但 "incomplete".
如果我 运行 手动 xslt 文件,我得到
Process is terminated due to WhosebugException
但是 XslCompiledTransform.Transform()
会挂起我的应用程序 永远 。
所以,我想在超时时结束该调用,但我尝试过的任何方法似乎都不起作用。它仍然挂起应用程序。
我希望有 try 块的线程不被挂起。我想创建两个任务,一个用于转换,另一个用于超时。然后同时启动两者。我不知道,但我认为 Run
在外部语句有机会连接超时并使用 WhenAny
之前 运行ning。
如何解决这个问题?
更新
我更新了代码以反映我当前的尝试。如果超时,我可以进入 if
块,但无论我是否中止线程,应用程序仍然挂起。我不明白 XslCompiledTransform.Transform
坚持在应用程序出现故障时将整个应用程序关闭是什么意思。
public static Object Load(string mathML)
{
if (mathML == Notebooks.InputCell.EMPTY_MATH)
return null;
XmlDocument input = new XmlDocument();
input.LoadXml(mathML);
XmlDocument target = new XmlDocument(input.CreateNavigator().NameTable);
using (XmlWriter writer = target.CreateNavigator().AppendChild())
{
try
{
Thread thread = null;
var task = Task.Run(() =>
{
thread = Thread.CurrentThread;
XmlTransform.Transform(input, writer);
});
if (!task.Wait(TimeSpan.FromSeconds(5)))
{
thread.Abort();
throw new TimeoutException();
}
}
catch (XsltException xex)
{
if (xex.Message == "An item of type 'Attribute' cannot be constructed within a node of type 'Root'.")
return null;
else
throw;
}
}
return Load(target);
}
这是我解决问题的方法
我将我的 xsl 编译成一个程序集,并从我的项目(称为 Library
)中引用该程序集
优点:
- 修复了挂起问题
- 将 xslt 编译成程序集据说要快得多
缺点:
- 你告诉我!我不知道:)
库属性/生成事件/预生成事件
"C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.7 Tools\xsltc.exe" /settings:script+ /class:Transform "myStylesheet.xslt"
图书馆/参考文献
+ myStylesheet.dll
正在加载编译的转换
private static XslCompiledTransform xslTransform;
private static XslCompiledTransform XslTransform
{
get
{
if (xslTransform == null)
{
xslTransform = new XslCompiledTransform();
xslTransform.Load(typeof(Transform));
}
return xslTransform;
}
}
调用转换
与问题中的更新代码相同
XslCompiledTransform.Transform
在某些情况下(堆栈溢出、无限循环等)会挂起。这是一个依赖于数据(输入)的错误,所以我无法完全控制它的发生。如果发生这种情况,我希望得到优雅的通知,但我不希望它破坏我的应用程序进程以及用户输入输入的 GUI,这可能是 "valid" 但 "incomplete".
如果我 运行 手动 xslt 文件,我得到
Process is terminated due to WhosebugException
但是 XslCompiledTransform.Transform()
会挂起我的应用程序 永远 。
所以,我想在超时时结束该调用,但我尝试过的任何方法似乎都不起作用。它仍然挂起应用程序。
我希望有 try 块的线程不被挂起。我想创建两个任务,一个用于转换,另一个用于超时。然后同时启动两者。我不知道,但我认为 Run
在外部语句有机会连接超时并使用 WhenAny
之前 运行ning。
如何解决这个问题?
更新
我更新了代码以反映我当前的尝试。如果超时,我可以进入 if
块,但无论我是否中止线程,应用程序仍然挂起。我不明白 XslCompiledTransform.Transform
坚持在应用程序出现故障时将整个应用程序关闭是什么意思。
public static Object Load(string mathML)
{
if (mathML == Notebooks.InputCell.EMPTY_MATH)
return null;
XmlDocument input = new XmlDocument();
input.LoadXml(mathML);
XmlDocument target = new XmlDocument(input.CreateNavigator().NameTable);
using (XmlWriter writer = target.CreateNavigator().AppendChild())
{
try
{
Thread thread = null;
var task = Task.Run(() =>
{
thread = Thread.CurrentThread;
XmlTransform.Transform(input, writer);
});
if (!task.Wait(TimeSpan.FromSeconds(5)))
{
thread.Abort();
throw new TimeoutException();
}
}
catch (XsltException xex)
{
if (xex.Message == "An item of type 'Attribute' cannot be constructed within a node of type 'Root'.")
return null;
else
throw;
}
}
return Load(target);
}
这是我解决问题的方法
我将我的 xsl 编译成一个程序集,并从我的项目(称为 Library
)中引用该程序集
优点:
- 修复了挂起问题
- 将 xslt 编译成程序集据说要快得多
缺点:
- 你告诉我!我不知道:)
库属性/生成事件/预生成事件
"C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.7 Tools\xsltc.exe" /settings:script+ /class:Transform "myStylesheet.xslt"
图书馆/参考文献
+ myStylesheet.dll
正在加载编译的转换
private static XslCompiledTransform xslTransform;
private static XslCompiledTransform XslTransform
{
get
{
if (xslTransform == null)
{
xslTransform = new XslCompiledTransform();
xslTransform.Load(typeof(Transform));
}
return xslTransform;
}
}
调用转换
与问题中的更新代码相同