コードの詳細:
// Singleton class CollectionObject
public class CollectionObject
{
private static CollectionObject instance = null;
// GetInstance() is not called from multiple threads
public static CollectionObject GetInstance()
{
if (CollectionObject.instance == null)
CollectionObject.instance = new CollectionObject();
return CollectionObject.instance;
}
// Dictionary object contains Service ID (int) as key and Service object as the value
// Dictionary is filled up during initiation, before the method call ReadServiceMatrix detailed underneath
public Dictionary<int, Service> serviceCollectionDictionary = new Dictionary<int,Service>();
public Service GetServiceByIDFromDictionary(int servID)
{
if (this.serviceCollectionDictionary.ContainsKey(servID))
return this.serviceCollectionDictionary[servID];
else
return null;
}
}
DataTable serviceMatrix = new DataTable();
// Fill serviceMatrix data table from the database
private int ReadServiceMatrix()
{
// Access the Singleton class object
CollectionObject collectionObject = CollectionObject.GetInstance();
// Parallel processing of the data table rows
Parallel.ForEach<DataRow>(serviceMatrix.AsEnumerable(), row =>
{
//Access Service ID from the Data table
string servIDStr = row["ServID"].ToString().Trim();
// Access other column details for each row of the data table
string currLocIDStr = row["CurrLocId"].ToString().Trim();
string CurrLocLoadFlagStr = row["CurrLocLoadFlag"].ToString().Trim();
string nextLocIDStr = row["NextLocId"].ToString().Trim();
string nextLocBreakFlagStr = row["NextLocBreakFlag"].ToString().Trim();
string seqStr = row["Seq"].ToString().Trim();
int servID = Int32.Parse(servIDStr);
int currLocID = Int32.Parse(currLocIDStr);
int nextLocID = Int32.Parse(nextLocIDStr);
bool nextLocBreakFlag = Int32.Parse(nextLocBreakFlagStr) > 0 ? true : false;
bool currLocBreakFlag = Int32.Parse(CurrLocLoadFlagStr) > 0 ? true : false;
int seq = Int32.Parse(seqStr);
// Method call leading to the issue (definition in Collection Object class)
// Fetch service object using the Service ID from the DB
Service service = collectionObject.GetServiceByIDFromDictionary(servID);
// Call a Service class method
service.InitLanes.Add(new Service.LaneNode(currLoc.SequentialID, currLocBreakFlag, nextLoc.SequentialID, nextLocBreakFlag, seq));
}
発生する問題は次のとおりです。
ディクショナリ内のすべての Service オブジェクトに対する上記のコードでは、後続のメソッド呼び出しが行われないため、以降の処理で問題が発生します。並列モードで辞書から Service オブジェクトをフェッチする必要があります
辞書にはすべての Ids /Service オブジェクトが含まれていますが、Singleton クラスの Parallel モードで処理する場合、いくつかのオブジェクトがスキップされて問題が発生することを理解しています。
私の理解では、渡されたサービス ID と作成されたサービス オブジェクトはスレッドに対してローカルであるため、直面している問題はありません。この種の問題は、特定のメソッド呼び出しに対して、あるスレッドが別のスレッドのサービス ID 値をそのスレッドで置き換える場合にのみ可能です。したがって、両方が Service オブジェクトになり、スキップされるものはほとんどありません。この場合のマルチスレッドを正しく理解していません
現在、Parallel.ForEach / Parallel.Invoke の代わりに foreach ループを使用して、非スレッド モードで同じコードを実行できます。
確認して、問題の解決に役立つ見解や指針をお知らせください