2012-08-14 74 views
1

當運行這個程序時,有時候這個異常有一個堆棧跟蹤,它起源於一個開始「拋出新的異常...」的行,但偶爾它有一個堆棧跟蹤,它起源於Parallel.For代表的第一個大括號。爲什麼會有這個行號?Parallel.For - 異常行號似乎是錯的

using System.Collections.Concurrent; 
using System.Threading.Tasks; 
using System; 
public class J 
{ 
    public static void Main() 
    { 
     ConcurrentDictionary<string, int> exceptions = new ConcurrentDictionary<string, int>(); 

     Parallel.For(0, 10, (i, s) => 
     { //this is line 55 
      try 
      { 
       throw new Exception("blah"); //line 58 
      } 
      catch (Exception e) 
      { 
       string estring = e.ToString(); 
       exceptions.TryAdd(estring, 0); 
       lock (exceptions) 
       { 
        exceptions[estring] += 1; 
       } 
      } 
     }); 

     foreach (var entry in exceptions) 
     { 
      Console.WriteLine("==============" + entry.Value + " times"); 
      Console.WriteLine(entry.Key); 
     } 
    } 
} 

這裏是怪異的輸出

==============3 times 
System.Exception: blah 
    at J.<>c__DisplayClass5.<Main>b__4(Int32 i, ParallelLoopState s) in Program.cs:line 55 
==============7 times 
System.Exception: blah 
    at J.<>c__DisplayClass5.<Main>b__4(Int32 i, ParallelLoopState s) in Program.cs:line 58 
Press any key to continue . . . 

我修改後的代碼,包括System.Threading.Thread.CurrentThread.ManagedThreadId e.ToString前()。 我必須運行它大約20次,然後才能重現它,並在第55行產生異常。 從下面的輸出中,我可以看出Goz是正確的;它對一些並行任務使用主線程(線程標識1),但它的主線程有兩個正確的行號,然後在主線程中有一次錯誤的號碼。 所以仍然神祕。

==============3 times 
5 - System.Exception: blah 
    at J.<>c__DisplayClass5.<Main>b__4(Int32 i, ParallelLoopState s) in Program.cs:line 58 
==============1 times 
6 - System.Exception: blah 
    at J.<>c__DisplayClass5.<Main>b__4(Int32 i, ParallelLoopState s) in Program.cs:line 58 
==============2 times 
1 - System.Exception: blah 
    at J.<>c__DisplayClass5.<Main>b__4(Int32 i, ParallelLoopState s) in Program.cs:line 58 
==============1 times 
1 - System.Exception: blah 
    at J.<>c__DisplayClass5.<Main>b__4(Int32 i, ParallelLoopState s) in Program.cs:line 55 
==============2 times 
4 - System.Exception: blah 
    at J.<>c__DisplayClass5.<Main>b__4(Int32 i, ParallelLoopState s) in Program.cs:line 58 
==============1 times 
3 - System.Exception: blah 
    at J.<>c__DisplayClass5.<Main>b__4(Int32 i, ParallelLoopState s) in Program.cs:line 58 
Press any key to continue . . . 

+0

注意:我想也許有一些JIT編譯奇怪發生,但我確認並非如此,通過更改parallel-for來調用具有相同主體的靜態方法,然後將該屬性添加到該方法: [MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)]所以還是個謎。 – Anssssss 2012-08-14 21:51:10

+0

只要注意,[msdn社區問題](https://social.msdn.microsoft.com/Forums/en-US/f1e6988d-aeb4-4d2c-8f3f-e5eabad55a33/parallelfor-exception-line-number-in- stacktrace-seem-wrong?forum = parallelextensions)我問過去哪兒都沒有,並且[Connect問題](https://connect.microsoft.com/VisualStudio/feedback/details/771771/parallel-for-exception-line-number-有時是錯誤的)我提交被標記爲「不會解決」沒有任何解釋。 – Anssssss 2017-09-13 14:58:08

回答

2

的Parallel.For是一個奇怪的野獸調試。你看到的行號是指lambda塊本身(即它發生在這裏的某處)。

最好我設法解決的是行號取決於哪個線程拋出異常。這似乎是正確的,當異常是從主線程拋出...

會愛比這更好的答案雖然:)

+0

你說「你看到的行號......」,但我看到有*兩行*號。沒有任何異常從主線程拋出。如果主線程拋出了一個異常,它將不會被捕獲到任何地方,我只捕獲Parallel For線程執行的lambda中的異常。 – Anssssss 2012-09-17 15:29:34

+0

不是parallel.for在不同線程上運行的所有迭代。一些迭代運行在主/調用線程上。 – Goz 2012-09-17 17:40:46

+0

我測試了一下,你說得對,它使用了主線程。但是,您對行號是否正確的假設並非總是如此。我能夠產生一個案例,主線程報告55號線上的例外情況(請參閱編輯原始帖子)。 – Anssssss 2012-09-18 19:41:38

0

,斷點可以關閉,如果.pdb文件不同步,與.dll文件。嘗試一個乾淨的和重建。如果這不起作用,請手動刪除Windows資源管理器中的文件並重新構建。

+0

這不會導致有時報告一行,有時報告另一個程序的範圍內的一個單一的執行 – Servy 2012-08-14 20:52:16

+0

@Servy - The OP說:「有時候這個例外有一個堆棧跟蹤......」他沒有定義什麼時候或者怎麼樣,你從哪裏得到這些信息? – 2012-08-14 20:54:51

+0

我查看了他的程序代碼,看看它在做什麼,輸出。只有一個地方拋出一個異常,一個地方記錄它,記錄它的可理解代碼,以及一個輸出,正如我在我的評論中所說的那樣,表示堆棧跟蹤與7個在同一個程序中從同一行中拋出10個異常。 – Servy 2012-08-14 20:57:02