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

Windows Forms异步执行后台SIM卡读取任务时同步显示进度条

解决Windows Forms中进度条与后台函数同步运行的问题

原代码的核心问题是两个函数都在UI线程同步执行:barraProgresso里的Thread.Sleep会直接阻塞UI线程,后续的run_background_function也会占用UI线程,导致整个应用失去响应。下面用async/await和Task.Run实现并行执行,同时保证UI正常响应:

修改后的完整代码

private async void button1_Click(object sender, EventArgs e)
{
    // 禁用按钮避免重复触发
    button1.Enabled = false;

    // 同时启动两个异步任务
    var progressTask = barraProgresso(5000);
    var backgroundTask = Task.Run(() => run_background_function());

    // 等待两个任务全部完成
    await Task.WhenAll(progressTask, backgroundTask);

    // 任务完成后恢复按钮状态
    button1.Enabled = true;
}

private async Task barraProgresso(int tempo)
{
    progressBar1.Value = 0;
    int stepDelay = tempo / 100;

    for (int progresso = 0; progresso <= 100; progresso++)
    {
        progressBar1.Value = progresso;
        // 用Task.Delay替代Thread.Sleep,不会阻塞UI线程
        await Task.Delay(stepDelay);
    }
}

private void run_background_function()
{
    // 这里放读取SIM卡的耗时逻辑,模拟5秒耗时
    Thread.Sleep(5000);

    // 如果需要更新UI(比如提示读取完成),必须切换回UI线程
    this.Invoke((MethodInvoker)delegate {
        MessageBox.Show("SIM卡读取完成");
    });
}

关键改动说明

  1. 异步按钮事件:将button1_Click标记为async void(WinForms事件处理允许该写法),内部用await等待异步任务完成,不会阻塞UI线程。
  2. 后台任务线程池执行:用Task.Run将run_background_function放到线程池线程执行,彻底与UI线程解耦,避免UI无响应。
  3. 异步进度条更新:把barraProgresso改为async Task方法,用await Task.Delay替代Thread.Sleep——前者会释放UI线程,让界面能实时更新进度条并响应系统消息。
  4. 任务同步等待:Task.WhenAll确保进度条动画和后台读取操作都完成后,再恢复按钮状态,避免用户重复操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 16:25:17