List<TaskClass> TaskList
Parallel ループを使用して繰り返し処理できる項目があります。
リスト内の項目は、TaskClass が独自のCompareTo(object obj)
メソッドで IComparable を実装するため、特定の順序で並べ替えられます。したがって、アイテムを順番に処理する必要があります。
順番に完了する必要はなく、順番に開始するだけであることに注意してください。
したがって、TaskList[0] を最初に開始する必要があります。次に、TaskList[1]、TaskList[2]、... ただし、TaskList[2] が最初に完了するか、TaskList[0] かは気にしません。
これは、これを試して軽減するために思いついた簡単なコードです。
//Construct a ConcurrentQueue and populate it with our SORTED list
//of TaskClass items so when we go through a parallel loop
//they are acted upon in sorted order. A parallel loop does not
//guarantee ordering, which we need to make sure tasks with a higher
//number are done first.
ConcurrentQueue<TaskClass> cq = new ConcurrentQueue<TaskClass>();
for (int x = 0; x < TaskList.Count; x++)
cq.Enqueue(TaskList[x]);
Parallel.For(
0,
cq.Count,
new ParallelOptions { MaxDegreeOfParallelism = DISystem.MaxConcurrentThreads },
x =>
{
TaskClass tc = null;
if (cq.TryDequeue(out tc))
{
TaskTypeManager ttm = new TaskTypeManager();
tc.Working = true;
tc.Started = DateTime.Now;
ttm.ProcessTaskItem(tc);
}
}
);
今私が信じている問題は、Parallel.For ループが完了したときに、オリジナルList<TaskClass> TaskList
が最新の値で更新されていないことです。
これを達成するための最良の方法は何ですか?
次のような変更されたコードで?(「//new」でマークされた行)
ConcurrentQueue<TaskClass> cq = new ConcurrentQueue<TaskClass>();
for (int x = 0; x < TaskList.Count; x++)
cq.Enqueue(TaskList[x]);
List<TaskClass> NewTaskList = new List<TaskClass>(); //new
object lockObject = new Object(); //new
Parallel.For(
0,
cq.Count,
new ParallelOptions { MaxDegreeOfParallelism = DISystem.MaxConcurrentThreads },
x =>
{
TaskClass tc = null;
if (cq.TryDequeue(out tc))
{
TaskTypeManager ttm = new TaskTypeManager();
tc.Working = true;
tc.Started = DateTime.Now;
ttm.ProcessTaskItem(tc);
lock (lockObject) //new
{
NewTaskList.Add(tc);
}
}
}
);
NewTaskList.Sort(); //new
TaskList.Clear(); //new
TaskList = NewTaskList.ToList(); //new
または、他のアイデア/提案/改善点はありますか?
ありがとう!