1

このプログラムを実行すると、"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 . . .

4

2 に答える 2

2

Parallel.For は、デバッグするのが厄介です。表示されている行番号は、ラムダ ブロック自体を参照しています (つまり、ここのどこかで発生しました)。

私がこれまでに解決した最高のことは、行番号が例外をスローするスレッドに依存することです。メインスレッドから例外がスローされた場合は正しいようです...

それよりも良い答えが欲しいです:)

于 2012-08-14T20:49:45.230 に答える
0

.pdbファイルが .dll と同期していない場合、ブレークポイントがオフになることがあります。クリーンとリビルドを試してください。それでもうまくいかない場合は、Windows エクスプローラーでファイルを手動で削除し、再度ビルドしてください。

于 2012-08-14T20:50:01.833 に答える