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

如何使用EventHandler与Parallel.For实现控制台进度条递增

实现控制台进度条结合EventHandler与Parallel.For

1. 给Executer类添加进度更新事件

在Executer类中定义进度更新事件,让外部可以订阅该事件同步更新进度条:

public class Executer
{
    // 定义进度更新事件,传递当前进度百分比
    public event EventHandler<int> ProgressUpdated;

    private int _progress = 0;
    private readonly int _totalTasks = 99; // 对应Parallel.For(1,100)的99个任务

    public void Execute()
    {
        Parallel.For(1, 100, i =>
        {
            DoSomething();
            // 原子性递增进度值,避免多线程冲突
            int newProgress = Interlocked.Increment(ref _progress);
            // 触发进度更新事件
            OnProgressUpdated(newProgress);
        });
        // 任务全部完成后触发100%进度
        OnProgressUpdated(_totalTasks);
    }

    private void DoSomething()
    {
        // 模拟耗时业务操作
        Thread.Sleep(50);
    }

    // 线程安全的事件触发方法
    protected virtual void OnProgressUpdated(int currentProgress)
    {
        int percentage = (int)Math.Round((double)currentProgress / _totalTasks * 100);
        ProgressUpdated?.Invoke(this, percentage);
    }
}

2. 实现控制台进度条组件

整合控制台进度条的核心逻辑,直接嵌入项目中:

public class ConsoleProgressBar
{
    private const int BarWidth = 50;
    private readonly char _filledChar = '█';
    private readonly char _emptyChar = '░';

    public void Update(int percentage)
    {
        // 确保百分比在0-100区间内
        percentage = Math.Clamp(percentage, 0, 100);

        // 移动光标到当前行开头,覆盖之前的进度条内容
        Console.CursorLeft = 0;

        // 计算进度条填充长度
        int filledLength = (int)Math.Round(BarWidth * percentage / 100.0);
        string bar = new string(_filledChar, filledLength) + new string(_emptyChar, BarWidth - filledLength);

        // 输出进度条与百分比
        Console.Write($"[{bar}] {percentage,3}%");

        // 进度完成后换行,避免后续输出覆盖进度条
        if (percentage == 100)
        {
            Console.WriteLine();
        }
    }
}

3. 在主程序中绑定事件并启动任务

在Main方法里订阅进度更新事件,同步更新控制台进度条:

class Program
{
    static void Main(string[] args)
    {
        var progressBar = new ConsoleProgressBar();
        var executer = new Executer();

        // 订阅进度更新事件,线程安全地更新进度条
        executer.ProgressUpdated += (sender, percentage) =>
        {
            lock (progressBar)
            {
                progressBar.Update(percentage);
            }
        };

        Console.WriteLine("任务启动...");
        executer.Execute();
        Console.WriteLine("任务完成!");
    }
}

关键注意事项

  • 线程安全:用Interlocked.Increment保证进度值的原子性;控制台输出加lock,避免多线程同时写入导致的界面混乱。
  • 事件触发:通过OnProgressUpdated方法触发事件,用?.Invoke避免空引用异常。
  • 进度准确性:根据总任务数计算百分比,确保进度条最终能显示100%完成状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 00:20:27