2016-06-09 86 views
-2

我是C#的全新人物,儘管在使用其他語言方面有一些小的經驗,並且遇到了困難。C#Parallel.Foreach with XML

下面的代碼工作完全按照預期:

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的,動作)」不能從使用推斷。 嘗試明確指定類型參數。

實施例下面的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> 

任何援助將不勝感激。

+7

什麼問題? – SLaks

+0

另外,[文檔](https://msdn.microsoft.com/en-us/library/system.xml.xmldocument(v = vs.110).aspx)聲明'XmlDocument'不能保證線程安全。儘管查詢不太可能會導致問題,但這可能存在風險。你真的在單線程的情況下有性能問題嗎? –

+0

@Charles Mager,如果你只是閱讀,我相信XmlDocument應該跨線程。 –

回答

0

您需要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(); 
    } 
+0

就解決方案而言,這是顯而易見的。我也能夠使用doc.load(「config.xml」),這正是我正在尋找的。我需要詳細閱讀Casting非泛型的細節,因爲我真的不明白atm是什麼意思,但現在我有一些東西要針對。乾杯! – Majickal

+0

沒問題,祝你好運! –

0

控制檯中顯示的項目是否無序? 您可以安全地從多個線程調用Console.WriteLine,但我不會指望按預期順序實際寫入控制檯的項目。我期望他們通常被寫入預期的序列,然後有時不會。這是多線程執行的行爲。它會做你期望它做的事情,但是永遠不會指望它按預期的順序發生,即使你反覆測試一遍又一遍,它確實發生在預期的順序中。

+0

感謝您的回答@Scott,我在並行執行後專門針對速度回報和避免執行隊列,因爲我正在編寫的應用程序依賴於響應時間而不是響應順序。 – Majickal