2012-08-14 112 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