You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

进度条进度与文件数量不匹配的原因排查及解决方法

问题解决方案

一、已处理图片计数翻倍(显示70而非35)的原因及修复

原因

  1. 重复订阅PropertyChanged事件:每次调用StartDownload方法时,都会给_radar.PropertyChanged新增一个事件处理逻辑。如果该方法被触发多次(比如重复点击开始按钮),同一个State变更会触发多轮计数递增,最终导致数值翻倍。
  2. 循环逻辑冗余:当前ProcessDownloadedImagesAsync中,先获取所有PNG文件再逐个判断是否包含_Processed,循环次数等于总PNG文件数(原文件+处理后文件),虽然不会直接导致计数翻倍,但会增加不必要的循环开销。

修复方案

1. 避免重复订阅事件

将事件处理逻辑提取为独立方法,订阅前先移除旧的处理程序,确保同一事件只触发一次计数:

private void StartDownload()
{
    // 先移除旧的事件绑定,防止重复订阅
    _radar.PropertyChanged -= Radar_PropertyChanged;
    _radar.PropertyChanged += Radar_PropertyChanged;
    
    // 原有定时器启动代码...
}

// 独立的事件处理方法
private void Radar_PropertyChanged(object sender, PropertyChangedEventArgs args)
{
    switch (args.PropertyName)
    {
        case nameof(_radar.State):
            BeginInvoke((MethodInvoker)delegate
            {
                if (_radar.State == RadarState.ImageProcessed)
                {
                    successfulDownloadsCount++;
                    lblImagesCounter.Text = $"Images Count: {successfulDownloadsCount}";
                }
                else if (_radar.State == RadarState.ImageProcessing)
                {
                    Text = "Radar - ImagesProcessing";
                }
                else
                {
                    Text = $"Radar - {_radar.State}";
                }
            });
            break;
        case nameof(_radar.Progress):
            if (!Disposing) BeginInvoke((MethodInvoker)delegate
            {
                _downloadProgress.Value = _radar.Progress;
            });
            break;
    }
}

2. 优化处理循环(可选)

提前过滤需要处理的文件,减少循环次数,同时在Radar类内部维护计数,避免UI层依赖状态变更计数:

// Radar类新增属性
public class Radar : INotifyPropertyChanged
{
    private int _processedImagesCount;
    public int ProcessedImagesCount
    {
        get => _processedImagesCount;
        set
        {
            if (_processedImagesCount != value)
            {
                _processedImagesCount = value;
                OnPropertyChanged();
            }
        }
    }

    private async Task ProcessDownloadedImagesAsync()
    {
        Progress = 0;
        ProcessedImagesCount = 0;

        // 提前过滤出需要处理的文件,减少循环次数
        List<string> filesToProcess = Directory.GetFiles(Folder, "*.png")
            .Where(file => !file.Contains("_Processed"))
            .ToList();

        if (filesToProcess.Count > 0)
        {
            for (int i = 0; i < filesToProcess.Count; i++)
            {
                State = RadarState.ImageProcessing;
                new RadarImagesConvertor(filesToProcess[i], Folder);
                State = RadarState.ImageProcessed;
                
                ProcessedImagesCount++;
                Progress = (int)((double)(i + 1) / filesToProcess.Count * 100);
                
                await Task.Delay(50);
            }
        }
    }
}

UI层直接监听ProcessedImagesCount变更:

// 在Radar_PropertyChanged方法中新增case
case nameof(_radar.ProcessedImagesCount):
    BeginInvoke((MethodInvoker)delegate
    {
        lblImagesCounter.Text = $"Images Count: {_radar.ProcessedImagesCount}";
    });
    break;

二、下载进度条与实际成功下载数量不同步的原因及修复

原因

当前DownloadImagesAsync中,无论文件是否成功下载(包括已存在、下载失败),completedFiles都会递增,进度计算基于总链接数而非实际成功下载的新文件数。即使仅成功下载35个,循环200次后进度仍会拉满到100%。

修复方案

仅在成功下载新文件时更新计数和进度,确保进度条反映真实下载情况:

private async Task DownloadImagesAsync()
{
    Progress = 0;
    int totalPending = Links.Count;
    int successCount = 0;

    if (Links.Any())
    {
        State = RadarState.Downloading;

        using (HttpClient client = new HttpClient())
        {
            foreach (var link in Links)
            {
                var fileName = LinksAndFileNames[link];
                var filePath = Path.Combine(Folder, fileName + ".png");

                try
                {
                    if (!File.Exists(filePath))
                    {
                        byte[] fileData = await client.GetByteArrayAsync(link);
                        File.WriteAllBytes(filePath, fileData);
                        successCount++;
                        // 实时更新进度
                        Progress = (int)((double)successCount / totalPending * 100);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"下载失败: {ex.Message}");
                    // 失败时不更新计数和进度
                }
            }
        }
    }

    State = RadarState.DownloadCompleted;
    // 可选:如果需要进度条最终拉满,保留下面一行;否则注释掉,进度停在实际成功比例
    // Progress = 100;
    await Task.Delay(2000);
}

内容的提问来源于stack exchange,提问作者Daniel Lip

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 17:07:05