You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

UserDialog进度条不显示且无法递增问题求助(附代码)

问题分析与解决方案

看起来你这进度条的问题主要出在三个核心点上,咱们一个个拆解:

1. 进度条更新脱离了UI线程

你用了ConfigureAwait(false),这会让后续代码脱离UI上下文运行。而Mvx的IUserDialogs进度条属于UI控件,必须在UI线程更新状态,不然界面根本接收不到更新信号——这就是进度条一直卡在2%不动的直接原因。

2. 循环逻辑完全不符合预期

现在的代码是每次循环都完整执行一遍SyncPopulationData(countryId),然后硬把进度条加2%,直到到100%。这意味着你会重复执行50次同步任务,而且进度条的数值和实际任务进度毫无关系,完全是虚假的“伪进度”。

3. 没有跟踪任务的真实进度

你的同步任务SyncPopulationData没有提供任何进度反馈,进度条的数值是你手动硬加的,既不真实,也没办法反映任务的实际执行情况。


修复后的代码示例

首先,咱们得让SyncPopulationData支持进度报告,比如传入一个IProgress<int>来传递实时进度:

// 修改同步方法,添加进度报告能力
private void SyncPopulationData(string countryId, IProgress<int> progress)
{
    // 假设你的同步任务拆分为10个核心步骤(根据实际业务调整)
    var totalSteps = 10;
    for (int i = 0; i < totalSteps; i++)
    {
        // 执行当前步骤的实际操作(比如下载数据、写入数据库等)
        ExecuteStep(countryId, i);
        
        // 计算当前进度并上报
        int currentProgress = (i + 1) * 10;
        progress.Report(currentProgress);
        
        // 模拟耗时操作(实际项目中可移除)
        Thread.Sleep(500);
    }
}

然后修改异步方法,正确跟踪进度并在UI线程更新进度条:

public async Task SyncPopulationDataAsync(string countryId)
{
    var cancelled = false;
    using (var dlg = Mvx.Resolve<IUserDialogs>().Progress("Test Progress", () => cancelled = true))
    {
        // 创建进度对象,自动在UI线程处理进度更新
        var progress = new Progress<int>(percent =>
        {
            if (!cancelled && percent <= 100)
            {
                dlg.PercentComplete = percent;
            }
        });

        // 仅执行一次同步任务,传入进度对象
        await Task.Run(() => 
        {
            if (!cancelled)
            {
                SyncPopulationData(countryId, progress);
            }
        });

        // 任务完成后确保进度条拉满
        if (!cancelled)
        {
            dlg.PercentComplete = 100;
        }
    }
}

关键修复点说明

  • IProgress<T>传递进度:这是.NET标准的进度报告方式,它会自动切换到创建它的线程(也就是这里的UI线程)处理回调,不用手动切换上下文。
  • 移除无效循环:不再重复执行同步任务,而是执行一次并跟踪真实进度。
  • 确保UI线程更新Progress<T>的回调会自动在UI线程执行,所以更新dlg.PercentComplete是安全的,界面会实时刷新。
  • 支持取消逻辑:可以在同步任务内部检查cancelled标志,提前终止任务(如果业务需要)。

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

火山引擎 最新活动