与任务完成相比,并行任务的进度条更新会延迟

问题描述 投票:0回答:1

我正在使用 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

c# .net winforms
1个回答
0
投票

您可能会被更新请求淹没进度条,并且进度条有一个内部延迟,在此期间它会将进度条动画化为新值。发送更少的更新,尤其是当它们很琐碎时(因此完成得非常快)。

更是如此,因为您在报告进度时无需等待单个任务的完成,您应该只在任务完成后报告进度,如下所示:

async Task UploadItemsHelper() { await Task.Run(() => UploadItems(item, progress)); Interlocked.Increment(ref counter); progress.Report(counter); } listOne.Add(UploadItemsHelper());
虽然您似乎对代码中的线程感到困惑——但您不需要互锁增量,因为它似乎首先在 GUI 线程上运行。这是代码的另一个大问题,所有内容都不断序列化回 GUI 线程。

© www.soinside.com 2019 - 2024. All rights reserved.