我试图根据id范围划分多个任务之间的工作 我有这个方法,基于i获取开始和结束范围。 我可以看到GetRanges方法正在将范围正确划分为任务。 但是当任务被称为StartWork(startRange,endRange)时,它有时会将所有任务设置为相同的范围 有时有2或3个重复范围。 异步任务启动时,基本上没有传递唯一的startrange和endRange?我该如何解决?
int endRange = 0;
int startRange = 0;
int total = GetTotal();
int startIndex =1;
for (int i = 0; i < taskCount; i++)
{
GetRanges(ref startRange, ref endRange, total, i, startIndex);
Console.WriteLine("startRange {0} EndRange {1}", startRange, endRange);
tasks[i] = Task.Factory.StartNew(() => StartWork(startRange, endRange));
}
private void StartWork(int startRange, int endRange)
{
Console.WriteLine("Thread {0} task startRange {1} EndRange {2}", System.Threading.Thread.CurrentThread.ManagedThreadId, startRange, endRange);
}
private void GetRanges(ref int startRange, ref int endRange, int total, int threadIndex, int startIndex)
{
int averagetask = (total - startIndex) / taskCount;
startRange = (averagetask * threadIndex) + 1;
if (threadIndex == taskCount - 1)
endRange = total;
else
endRange = averagetask * (threadIndex + 1);
}
这是输出 startRange 1 EndRange 785761 startRange 785762 EndRange 1571522 startRange 1571523 EndRange 2357283 startRange 2357284 EndRange 3143047
线程3任务startRange 2357284 EndRange 3143047 线程5任务startRange 2357284 EndRange 3143047 线程4任务startRange 2357284 EndRange 3143047 线程6任务startRange 2357284 EndRange 3143047
答案 0 :(得分:1)
小心使用ref参数并将它们传递给不同线程上的任务。我认为发生的事情是在任务查看该值时,它已经在另一个线程上被更改了。即你的StartWork方法正在查看startRange / endRange的当前值,该值不断被更改。
尝试这样做:
for (int i = 0; i < taskCount; i++)
{
GetRanges(ref startRange, ref endRange, total, i, startIndex);
Console.WriteLine("startRange {0} EndRange {1}", startRange, endRange);
var tempStartRange = startRange;
var tempEndRange = endRange;
tasks[i] = Task.Factory.StartNew(() => StartWork(tempStartRange, tempEndRange));
}