2016-07-27 7 views
0

いくつかの情報を確認するために、一連のデータ(以下のクエリの例)をページングしています。 Parallel.ForEachを使用すると、結果の2ページ目を取得するSQLコマンドが空に戻ります。 return文を壊してアクティブな行をリポジトリに戻すと、探している結果が返されます。 Parallel.ForEachを標準のC#foreachに変更すると、期待どおりに動作します。Parallel.ForEachを実行するとSQLクエリが機能しなくなる

クエリの例:コードの

SELECT TOP 500 
     StudentID, 
     StudentName 
    FROM Student 
    WHERE StudentVerified IS NULL 

例...

while(true) 
{ 
    using(var rep = new Repository()) 
    { 
     var students = rep.GetStudents(); 
     if (students.Length == 0) return false; 
     Parallel.ForEach(students, (student) => 
     { 
      rep.StudentVerified(student.StudentID, true); 
     }); 
    } 
} 

結果の2ページ目は空が高く評価されて戻って来ている理由を把握するためにすべてのヘルプ。ありがとう。

+2

'Repository.StudentVerified'はスレッドセーフではありません。あなたはそのコードを表示する必要があります。 –

+0

これは単純なSQL UPDATEステートメントです。ただし、スレッドセーフであるかどうかは関係ありません。SELECTコマンドでもデータが返されるか、例外が発生するはずです。結果を返すことは間違いありません。 – Brian

+2

_ "Parallel.ForEachを標準のC#foreachに変更すると、スコットのフォローアップとして、オプションで' MaxDegreeOfParallelism'を '1'に設定すると、期待通りに動作します。あまりにも。したがって、問題はあまりありません_ "Parallel.ForEachはSQLクエリを動作させません" _ではなく、コードがスレッドセーフではない可能性があります。 'Repository.StudentVerified'がすべて同じdb接続を共有している場合、おそらくあなたの問題でしょう。同じことがEF – MickyD

答えて

1

あなたのコメントから、リクエストの間にSqlConnectionを共有しているようです。そのクラスはスレッドセーフではありません。 SqlConnection is optimised to have many short lived connectionsの場合は、必要に応じて接続を作成し、完了したらusingブロックを使用して処分します。

+0

私は問題をよりよく理解しようとしています。なぜそれが黙って失敗しているのか分かりませんか? Parallel.ForEachの外部のコードが失敗しているのに、内部のコードではないのはなぜですか?この行動は私には全く直感的ではないようです。 – Brian

関連する問題