2013-10-11 13 views
3

我已經.NET 4.5中的Parallel.For循環調試失控線程

Parallel.For(0, fileArray.Length, i => 
      { 
       DataRow dataRow = table.NewRow(); 
       var dr = GetDataRow(fileArray[i], dataRow, parameters); 
       if (dr["MyVariable"].ToString() != "0") 
       { 
        try 
        { 
         table.Rows.Add(dr); 
        } 
        catch (Exception exception) 
        { 
         ConfigLogger.Instance.LogError(exception); 
        } 
       } 
      } 
     ); 

看似下運行下面的代碼隨機這個循環將最大程度的發揮機器的處理器和失速使得環路上沒有更多的進展。這是處理11k文件,我不能讓它重複使用一小套文件。有沒有人有任何想法如何調試,並找出是什麼原因造成的?我不能把它複製到我的機器上,並且我的機器和生產之間的差別如下

生產的Win 7 64位,.NET 4.5

發展贏8的64位,淨4.5.1

有沒有辦法在parallel.for循環的每個實例上放置超時異常?

+0

可能GetDataRow需要很多時間,因爲在這個循環中沒有其他可能。您是否嘗試使用相同的數據進行復制? – usr

+0

GetDataRow()是處理數據的東西,是我寫的函數。通常情況下,需要一兩秒......偶爾會出現,而且沒有解釋,環路卡住了。我還沒有想出一個方法來找出什麼文件或爲什麼它卡住。 – PlTaylor

+0

您是否嘗試使用相同的數據進行復制?也許處理過程需要很長的時間。循環不會卡住,循環中的代碼會卡住。 – usr

回答

3

正如評論中提到的那樣,您需要使用線程本地數據表,Parallel已經內置了對此的支持。也沒有理由使用Parallel.ForForEach會更適合這種情況。

Parallel.ForEach(fileArray, 
       () => 
        { 
         lock(table) 
         { 
          //Create a temp table per thread that has the same schema as the main table 
          return table.Clone(); 
         } 
        }, 
       (file, loopState, localTable) => 
        { 
         DataRow dataRow = localTable.NewRow(); 
         var dr = GetDataRow(file, dataRow, parameters); 
         if (dr["MyVariable"].ToString() != "0") 
         { 
          try 
          { 
           localTable.Rows.Add(dr); 
          } 
          catch (Exception exception) 
          { 
           ConfigLogger.Instance.LogError(exception); 
          } 
         } 
         return localTable; 
        }, 
       (localTable) => 
       { 
        lock (table) 
        { 
         //Merge in the thread local table to the master table 
         table.Merge(localTable); 
        } 
       }); 
+0

這個功能非常好,可以讓我擺脫一些其他的問題,因爲我缺乏線程安全性,因此我現在認爲這些問題正在發生。 – PlTaylor