このプログラムを実行すると、"throw new Exception..." で始まる行の 1 つから発生したスタック トレースが例外に含まれることがありますが、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 を含めるようにコードを変更しました。55 行目で例外を生成して再現できるようになるまで、約 20 回実行する必要がありました。以下の出力から、Goz が正しかったことがわかります。いくつかの並列タスクにメイン スレッド (スレッド ID 1) を使用していましたが、メイン スレッドから 2 回正しい行番号があり、次にメイン スレッドから 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 . . .