【问题标题】:C# Parallel.Foreach with XMLC# Parallel.Foreach 与 XML
【发布时间】:2016-06-09 15:16:27
【问题描述】:

我是 C# 的新手,虽然对其他语言有一些小经验并且碰壁了。

下面的代码完全符合预期:

XmlDocument doc = new XmlDocument();
doc.Load("config.xml");
foreach (XmlNode node in doc.DocumentElement.ChildNodes)
{
   string name = node.Attributes["name"].Value;
   string ips = node.Attributes["ip"].Value;
   string port = node.Attributes["port"].Value;
   Console.WriteLine(name + " | " + ips + ":" + port);
}

我得到了我所期望的零错误,但是下面的代码让我很难过。我希望有人能解释我做错了什么,因为我觉得我可能遗漏了一些基本的东西。

XmlDocument doc = new XmlDocument();
doc.Load("config.xml");
node = doc.DocumentElement.ChildNodes;
Parallel.ForEach(node,
      (item) => {
      string name = item.Attributes["name"].Value;
      string ips = item.Attributes["ip"].Value;
      string port = item.Attributes["port"].Value;
      Console.WriteLine(name + " | " + ips + ":" + port);
      });

我只是尝试并行运行循环的每次迭代。当我尝试编译时,出现以下错误:

CS0411 方法 'Parallel.ForEach 的类型参数 (IEnumerable, Action)' 不能从用法中推断出来。 尝试明确指定类型参数。

以下示例 XML:

<item name="pc01" ip="192.168.0.10" port="80"><!--PC01--></item>
<item name="pc02" ip="192.168.0.11" port="80"><!--PC02--></item>
<item name="pc03" ip="192.168.0.12" port="80"><!--PC03--></item>
<item name="pc04" ip="192.168.0.13" port="80"><!--PC04--></item>

任何帮助将不胜感激。

【问题讨论】:

  • 有什么问题?
  • 顺便说一句,the documentation 声明 XmlDocument 不能保证线程安全。尽管查询不太可能导致问题,但这可能存在风险。在单线程情况下你真的有性能问题吗?
  • @Charles Mager,如果您只是阅读,我相信 XmlDocument 跨线程应该没问题。
  • @SLaks,我有一个时间敏感的应用程序,如果 foreach 循环中的一次迭代由于执行时间而延迟,由于复合执行时间延迟,它将导致所有后续迭代出现问题。并行运行这些应该可以避免这个问题。
  • 很好奇为什么我对提出这个问题投了反对票?我在网上搜索答案,没有运气,在这个网站上搜索答案,没有运气,问了一个问题以了解我哪里出错并被否决,否决选民请解释他们的理由,并解释他们为什么会没有留下反对票的理由?

标签: c# xml parallel.foreach


【解决方案1】:

你需要Cast非泛型类型。完整的解决方案如下。

    static void Main(string[] args)
    {
        var xml="<root><item name='pc01' ip='192.168.0.10' port='80'><!--PC01--></item><item name='pc02' ip='192.168.0.11' port='80'><!--PC02--></item><item name='pc03' ip='192.168.0.12' port='80'><!--PC03--></item><item name='pc04' ip='192.168.0.13' port='80'><!--PC04--></item></root>";
        XmlDocument doc=new XmlDocument();
        // doc.Load("config.xml");
        doc.LoadXml(xml);
        var nodeList=doc.DocumentElement.ChildNodes;
        Parallel.ForEach(nodeList.Cast<XmlNode>(),
              item => {
                  string name=item.Attributes["name"].Value;
                  string ips=item.Attributes["ip"].Value;
                  string port=item.Attributes["port"].Value;
                  Console.WriteLine(name + " | " + ips + ":" + port);
              });

        Console.ReadLine();
    }

【讨论】:

  • 就解决方案而言,这是正确的。我还能够使用 doc.load("config.xml") 这正是我正在寻找的。我需要阅读有关 Casting non generic types 的详细信息,因为我真的不明白这意味着 atm,但现在我有一些目标。干杯!
【解决方案2】:

控制台中显示的项目是否乱序? 您可以安全地从多个线程调用Console.WriteLine,但我不会指望实际按预期顺序写入控制台的项目。我希望它们通常以预期的顺序编写,但有时不会。这就是多线程执行的行为。它会做你期望它做的事情,但永远指望它会按照预期的顺序发生,即使你一遍又一遍地测试它确实会按照预期的顺序发生。

【讨论】:

  • 感谢您的回答@Scott,我在并行执行之后专门针对返回速度和避免执行队列,因为我正在编写的应用程序依赖于响应时间而不是响应顺序。
猜你喜欢
  • 2016-11-10
  • 1970-01-01
  • 2011-06-27
  • 2012-08-14
  • 2012-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多