0
我遇到了涉及报告Parallel.ForEach内部进度的同步问题。我在控制台应用程序中重新创建了该问题的简化版本。该示例实际上只使用列表中的一个项目。下面的代码:IProgress <T>和Parallel.ForEach同步问题
class Program
{
static void Main(string[] args)
{
int tracker = 0;
Parallel.ForEach(Enumerable.Range(1, 1), (item) =>
{
var progress = new Progress<int>((p) =>
{
tracker = p;
Console.WriteLine(String.Format("{0}", p));
});
Test(progress);
});
Console.WriteLine("The last value is: {0}", tracker);
Console.ReadKey();
}
static void Test(IProgress<int> progress)
{
for (int i = 0; i < 20; i++)
{
progress.Report(i);
}
}
}
正如你所看到的,我希望看到最后行不输出最后,不包含20。但如果我删除进度报告和只写在这样的for循环输出:
class Program
{
static void Main(string[] args)
{
int tracker = 0;
Parallel.ForEach(Enumerable.Range(1, 1), (item) =>
{
tracker = Test();
});
Console.WriteLine("The last value is: {0}", tracker);
Console.ReadKey();
}
static int Test()
{
int i;
for (i = 0; i < 20; i++)
{
Console.WriteLine(i.ToString());
}
return i;
}
}
它像我期望的那样。据我所知,Parallel.ForEach为列表中的每个项目创建一个Task,并且IProgress捕获创建它的上下文。鉴于这是一个控制台应用程序,我认为这不重要。请帮助!
'Progress'将在单独的线程上运行它的代码。从“Test”到它的调用将作为事件发送。所以'Parallel.ForEach'将在'Progress'处理所有'Test'发送给它的值之前完成。即使没有'Parallel.ForEach',你也会看到类似的行为。 – juharr
你不需要调用'String.Format'。 – SLaks