我正在使用 Windows 窗体的 C#/.NET 应用程序中的进度条,该进度条是从并行运行的任务中更新的。每个任务都会调用进度条上的值更改 1 的次数,其次数与进度条中的步骤数完全相同。然而,尽管任务总是很快完成,但进度条完成之前会有大约 0.5 到 1 秒的延迟。
表格文件
var progress = new Progress<int>();
progress.ProgressChanged += (_, value) =>
{
progressBarUploading.Value = value;
};
其他文件
internal async Task UploadProject(IProgress<int> progress)
{
List<Task> listOne = new();
foreach (var item in Project.items)
{
//do some stuff
Interlocked.Increment(ref counter);
progress.Report(counter);
listOne.Add(Task.Run(() => UploadItems(item, progress)));
}
// Waits until all the Tasks are finished
await Task.WhenAll(listOne);
progress.Report(Project.itemCountTotal);
}
internal async Task UploadItems(AzureDevOpsPOSTitem item, IProgress<int> progress)
{
List<Task> listTwo = new();
foreach (var newItem in item.list)
{
// do some other stuff
Interlocked.Increment(ref counter);
progress.Report(counter);
listTwo.Add(Task.Run(() => UploadItems(newItem, progress)));
}
// Waits until all the Tasks are finished.
await Task.WhenAll(listTwo);
}
我怀疑这种延迟可能是由于 UI 线程处理进度更新而任务在单独的线程上完成所致。有没有办法确保进度条与任务完成同步更新,而不会出现延迟?
此外,我尝试在所有任务完成后使用
progress.Report(maxLength);
将进度条设置为100%,但它似乎没有按预期工作。进度条继续逐步增加(大概是由于已完成任务的 progress.Report
调用)。有没有办法在所有任务完成后立即将进度条设置为100%并停止未执行的progress.Reports
?
您可能会被更新请求淹没进度条,并且进度条有一个内部延迟,在此期间它会将进度条动画化为新值。发送更少的更新,尤其是当它们很琐碎时(因此完成得非常快)。
更是如此,因为您在报告进度时无需等待单个任务的完成,您应该只在任务完成后报告进度,如下所示:
async Task UploadItemsHelper()
{
await Task.Run(() => UploadItems(item, progress));
Interlocked.Increment(ref counter);
progress.Report(counter);
}
listOne.Add(UploadItemsHelper());
虽然您似乎对代码中的线程感到困惑——但您不需要互锁增量,因为它似乎首先在 GUI 线程上运行。这是代码的另一个大问题,所有内容都不断序列化回 GUI 线程。