我正在重写一些代码以使用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个元素)。这在顺序完成工作时效果很好,因为进度条只运行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。
答案 0 :(得分:1)
如果将进度除以lstDKCZ和lstPTST的长度怎么样?
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;
}
}
}
}