我有一些代码循环遍历记录列表,为每个记录启动一个导出任务,并在每次任务完成时将进度计数器增加 1,以便用户知道该过程进行了多长时间。
但根据循环的时间安排,我经常会看到输出显示较高的数字在较低的数字之前。
例如,我希望看到这样的输出:
Exporting A Exporting B Exporting C Exporting D Exporting E Finished 1 / 5 Finished 2 / 5 Finished 3 / 5 Finished 4 / 5 Finished 5 / 5
But instead I get output like this
Exporting A Exporting B Exporting C Exporting D Exporting E Finished 1 / 5 Finished 2 / 5 Finished 5 / 5 Finished 4 / 5 Finished 3 / 5
I don't expect the output to be exact since I'm not locking the value when I update/use it (sometimes it outputs the same number twice, or skips a number), however I wouldn't expect it to go backwards.
My test data set is 72 values, and the relevant code looks like this:
var tasks = new List<Task>();
int counter = 0;
StatusMessage = string.Format("Exporting 0 / {0}", count);
foreach (var value in myValues)
{
var valueParam = value;
// Create async task, start it, and store the task in a list
// so we can wait for all tasks to finish at the end
tasks.Add(
Task.Factory.StartNew(() =>
{
Debug.WriteLine("Exporting " + valueParam );
System.Threading.Thread.Sleep(500);
counter++;
StatusMessage = string.Format("Exporting {0} / {1}", counter, count);
Debug.WriteLine("Finished " + counter.ToString());
})
);
}
// Begin async task to wait for all tasks to finish and update output
Task.Factory.StartNew(() =>
{
Task.WaitAll(tasks.ToArray());
StatusMessage = "Finished";
});
输出可以在调试语句和 StatusMessage
输出中向后出现。
正确的方法是什么来计算一个循环中完成了多少个异步任务,这样这个问题就不会发生?
最佳答案
您会得到混合输出,因为计数器的递增顺序与 Debug.WriteLine(...)
方法的执行顺序不同。
要获得一致的进度报告,可以在任务中引入报告锁
tasks.Add(
Task.Factory.StartNew(() =>
{
Debug.WriteLine("Exporting " + valueParam );
System.Threading.Thread.Sleep(500);
lock(progressReportLock)
{
counter++;
StatusMessage = string.Format("Exporting {0} / {1}", counter, count);
Debug.WriteLine("Finished " + counter.ToString());
}
})
);
关于c# - 如何跟踪循环中完成了多少异步任务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15745567/