当运行这个程序时,有时异常有一个堆栈跟踪,它起源于一个开始“抛出新异常...”的行,但偶尔它有一个堆栈跟踪,它起源于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 . . .
我修改了代码以在e.ToString()之前包含System.Threading.Thread.CurrentThread.ManagedThreadId。 在我能够重现它之前,我必须运行它大约20次才能在第55行产生异常。 从下面的输出中,我可以看出Goz是对的;它使用主线程(线程ID 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 :(得分:2)
Parallel.For是一个奇怪的野兽来调试。你看到的行号是指lambda块本身(即它发生在这里的某个地方)。
最好的我曾经设法解决的是行号取决于哪个线程抛出异常。从主线程中抛出异常似乎是正确的......
虽然会喜欢比这更好的答案:)
答案 1 :(得分:0)
如果.pdb
文件与.dll不同步,则可以关闭断点。尝试清理和重建。如果这不起作用,请手动删除Windows资源管理器中的文件并重新构建。