如何对转换

时间:2017-10-25 19:47:50

标签: c# task-parallel-library

XslCompiledTransform.Transform将在某些条件下挂起(堆栈溢出,无限循环等)。这是一个依赖于数据(输入)的错误,因此我无法完全控制它。如果发生这种情况,我希望得到优雅的通知,但我不希望它破坏我的申请流程,因此也就是用户输入输入的GUI,这可能是"有效&# 34;但是"不完整"。

如果我手动运行xslt文件,我会

  

由于StackOverflowException

,进程终止

但是XslCompiledTransform.Transform()会挂起我的应用永远

所以,我想在暂停时把这个电话包起来,但我尝试的任何东西似乎都没有用。它仍然挂起了应用程序。

我希望没有挂起try块的线程。我想创建两个任务,一个用于Transform,另一个用于超时。然后同时开始。我不知道,但我认为Run在外部语句有机会连接超时并使用WhenAny之前正在运行。

如何解决这个问题?

更新

我更新了代码以反映我当前的尝试。如果超时,我可以进入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);
}

1 个答案:

答案 0 :(得分:2)

以下是我解决问题的方法

我拿了我的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;
  }
}

调用转换

与问题

中的更新代码相同