从嵌套的Parallel.ForEach更新进度条
本文关键字:更新 ForEach 嵌套 Parallel | 更新日期: 2023-09-27 18:28:25
我正在重写一些代码,以使用TPL而不是BackgroundWorkers,并同时实现多线程。我的一切都运行得很好(并行运行,取消也可以),但我不知道如何适当地更新我的进度条。这就是我到目前为止所做的(由于任务很大,所以不打算写完整的任务):
更新:我已经根据一些建议对代码进行了更新。
var progressHandler = new Progress<int>(value => { pgbOverviewProgressbar.Value = value; });
progress = progressHandler as IProgress<int>;
await Task.Run(() => taskGetOverviewData(ct), ct);
public void taskGetOverviewData(CancellationToken ct)
{
DateTime dtTime2 = DateTime.Now;
int totalcount = lstDKCZ.Count * lstPTST.Count;
double iCounter = 0;
Parallel.ForEach(lstDKCZ, item =>
{
Parallel.ForEach(lstPTST, item2 =>
{
//Lots of SQL queries and whatnot
double iCount = overview.Count();
foreach(var item3 in overview)
{
//Again lots of things happening
if (DateTime.Now > dtTime2.AddMilliseconds(15))
{
if (iCounter != iCount)
progress.Report(Convert.ToInt32((iCounter / iCount) * 100 / totalcount);
dtTime2 = DateTime.Now;
}
}
}
}
}
最多执行4次并行迭代(lstDKCZ中的2个元素和lstPTST中的2个子元素)。当按顺序进行工作时,这很好,因为progressbar只运行4次(我只希望它在整个过程中运行一次)。现在,它只是偶尔上下跳跃,但这是意料之中的,而且很容易理解原因(从4个不同的线程更新相同的变量)。
但我该如何处理呢?我在搜索答案时看到了锁定,但我不太明白如何在这种情况下实现它。
更新2:为每个场景制作4个不同的进度报告。如何合并它们?
if (DateTime.Now > dtTime2.AddMilliseconds(15))
{
if (iCounter != iCount)
{
//Make 4 different of these for each scenario
if (item == "DK" && item2 == "PT")
progress1.Report(Convert.ToInt32((iCounter / iCount) * 100))
dtTime2 = DateTime.Now;
}
}
然后我想要的(据我所知)是这样的东西:
totalprogress = (progress1 + progress2 + progress3 + progress4) / totalcount;
不过,我似乎无法做到这一点,因为我无法将进度转换为整数并将该值传递给totalprogress。
如果将进度除以lstDKCZ和lsPTST的长度如何?
int totalCount = lstDKCZ.Count * lstPTST.Count;
Parallel.ForEach(lstDKCZ, item =>
{
Parallel.ForEach(lstPTST, item2 =>
{
//Lots of SQL queries and whatnot
double iCount = overview.Count();
double iCounter = 0;
foreach(var item3 in overview)
{
//Again lots of things happening
if (DateTime.Now > dtTime2.AddMilliseconds(15))
{
if (iCounter != iCount)
progress.Report(Convert.ToInt32((iCounter / iCount) * 100 / totalCount);
dtTime2 = DateTime.Now;
}
}
}
}