0

複数の学生に対して以下のメソッドを呼び出すコードをアプリケーションで実行しています。

問題は、Student 並列インデックス変数を使用して別のメソッドを呼び出し、そのメソッドのローカル変数を使用してメッセージ レコードを挿入し、その Student のすべてのメッセージを 1 回保存することです。

データベースに挿入されたメッセージの ownerId が間違っている場合があります。

たとえば、StudentRecord ID 10 が所有するメッセージは、所有者 ID の値が 10 ではなく 17 に設定されて DB に挿入されます。17 は同じクラスの StudentId ですが、並列ループと混同されているようです。

並列ループについての私の理解では、ループ内のすべてにローカル変数の独自のインスタンスがあるため、index Student はローカル変数の独自のブロックを作成するため、StudentId がデータベースに誤って挿入されている方法がわかりません。

いくつかの悪い共有が起こっているに違いありません。これは実際に使用されるデータまたは変数ではありません。できるだけ単純化しようとしました。

var students = GetAllStudentsForThisClass();
Parallel.ForEach(
    students,
    new ParallelOptions {
        MaxDegreeOfParallelism = 5
    },
    student => {
        var dbThread = new StudentLifeRepository();
        var studentRecord = dbThread.GetStudentById(student.Id);
        var records = new List<Student_Messages>();
        do {
            StudentMessage.Statuses = //web api call, returns null when no Statuses are available from api

            foreach (var studentMessage in StudentMessage.Statuses) {
                var message = new Student_Messages();
                //this is where I think the problem lies
                message.ownerId = studentRecord.StudentId;

                message.CreatedDate = studentMessage.MessageDate;
                message.ID = studentMessage.MessageId;
                message.message = studentMessage.message;

                records.Add(studentMessage);
            }
            //this loop happens until No more messages are available for this student
        } while(StudentMessage.Statuses != null);

        //DistinctItemComparer is making sure All messageIds
        //are unique since that is used for primary key
        foreach (var pt in records.Distinct(new DistinctItemComparer())) {
            dbThread.Add(pt);
            dbThread.Save();
        }
    }  
); //close of parallel loop
4

1 に答える 1