导读:本期聚焦于小伙伴创作的《C#怎么制作进度条窗体?C#异步任务如何显示处理进度》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C#怎么制作进度条窗体?C#异步任务如何显示处理进度》有用,将其分享出去将是对创作者最好的鼓励。

在C# Windows Forms应用程序开发中,当我们需要执行文件读写、数据批量处理、网络请求等耗时操作时,直接在UI线程执行会导致界面无响应,而通过异步任务配合进度条窗体,既能保证界面流畅,又能让用户清晰了解任务执行状态。

C#怎么制作进度条窗体?C#异步任务如何显示处理进度

进度条窗体界面设计

首先新建一个Windows Forms项目,添加一个名为ProgressForm的窗体作为进度条窗体,在窗体上放置以下控件:

  • 一个ProgressBar控件,用于显示进度百分比
  • 一个Label控件,用于显示当前进度的文字描述
  • 一个Button控件,用于取消任务操作

窗体的基本属性设置如下:

控件名称属性
ProgressFormFormBorderStyleFixedDialog
ProgressFormMaximizeBoxfalse
ProgressBarMinimum0
ProgressBarMaximum100
ProgressBarStyleContinuous

进度条窗体核心代码实现

ProgressForm中添加以下属性和方法,用于接收外部传入的进度信息和取消任务的逻辑:

using System;
using System.Windows.Forms;

namespace ProgressBarDemo
{
    public partial class ProgressForm : Form
    {
        // 定义取消任务的委托和事件
        public event Action CancelTask;

        public ProgressForm()
        {
            InitializeComponent();
        }

        // 更新进度的方法,供外部调用
        public void UpdateProgress(int percent, string message)
        {
            if (this.InvokeRequired)
            {
                // 跨线程调用,切换到UI线程执行
                this.Invoke(new Action<int, string>(UpdateProgress), percent, message);
                return;
            }
            // 设置进度条值,确保值在合法范围内
            progressBar1.Value = Math.Max(progressBar1.Minimum, Math.Min(progressBar1.Maximum, percent));
            // 更新提示文字
            label1.Text = message;
        }

        // 取消按钮点击事件
        private void btnCancel_Click(object sender, EventArgs e)
        {
            CancelTask?.Invoke();
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        }

        // 窗体关闭时触发取消逻辑
        private void ProgressForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            CancelTask?.Invoke();
        }
    }
}

异步任务处理逻辑实现

我们使用BackgroundWorker组件来处理异步任务,它内置了进度报告和取消任务的功能,非常适合配合进度条使用。在主窗体中添加BackgroundWorker组件,然后编写以下逻辑:

using System;
using System.ComponentModel;
using System.Windows.Forms;

namespace ProgressBarDemo
{
    public partial class MainForm : Form
    {
        private BackgroundWorker backgroundWorker;

        public MainForm()
        {
            InitializeComponent();
            InitBackgroundWorker();
        }

        // 初始化BackgroundWorker组件
        private void InitBackgroundWorker()
        {
            backgroundWorker = new BackgroundWorker();
            // 支持报告进度
            backgroundWorker.WorkerReportsProgress = true;
            // 支持取消任务
            backgroundWorker.WorkerSupportsCancellation = true;
            // 绑定异步任务执行方法
            backgroundWorker.DoWork += BackgroundWorker_DoWork;
            // 绑定进度更新方法
            backgroundWorker.ProgressChanged += BackgroundWorker_ProgressChanged;
            // 绑定任务完成方法
            backgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;
        }

        // 启动异步任务的按钮点击事件
        private void btnStartTask_Click(object sender, EventArgs e)
        {
            if (backgroundWorker.IsBusy)
            {
                MessageBox.Show("当前有任务正在执行,请等待完成或取消后再启动");
                return;
            }
            // 创建进度条窗体
            ProgressForm progressForm = new ProgressForm();
            // 绑定取消任务事件
            progressForm.CancelTask += () =>
            {
                if (backgroundWorker.IsBusy)
                {
                    backgroundWorker.CancelAsync();
                }
            };
            // 启动异步任务,传入进度条窗体作为参數
            backgroundWorker.RunWorkerAsync(progressForm);
            // 显示进度条窗体,模态显示
            progressForm.ShowDialog();
        }

        // 异步任务执行逻辑
        private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            ProgressForm progressForm = e.Argument as ProgressForm;
            int totalCount = 100;
            for (int i = 0; i <= totalCount; i++)
            {
                // 检查是否收到取消请求
                if (worker.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }
                // 模拟耗时操作,每次循环休眠100毫秒
                System.Threading.Thread.Sleep(100);
                // 计算当前进度百分比
                int percent = (int)((double)i / totalCount * 100);
                // 报告进度,传入百分比和提示信息
                worker.ReportProgress(percent, $"正在处理第{i}项,共{totalCount}项");
            }
        }

        // 进度更新回调,在UI线程执行
        private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            // 获取传入的进度条窗体对象
            ProgressForm progressForm = (sender as BackgroundWorker).GetType()
                .GetField("asyncOperation", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)
                ?.GetValue(sender) is null ? null : (e.UserState as Tuple<ProgressForm, string>)?.Item1;
            // 更简便的方式:通过DoWork传入的参數获取窗体,这里调整逻辑
            // 实际开发中可以将进度条窗体存为成员变量,这里简化演示
            // 假设我们在RunWorkerAsync时传入了窗体,这里通过e.UserState获取
            if (e.UserState is string message)
            {
                // 实际场景中需要关联对应的进度条窗体,这里简化为弹出提示
                // 正确逻辑应该在DoWork中把窗体存到可访问的位置,这里仅展示进度更新逻辑
                // 演示用:直接输出进度信息
                Console.WriteLine($"当前进度:{e.ProgressPercentage}%,{message}");
            }
        }

        // 任务完成回调
        private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                MessageBox.Show("任务已取消");
            }
            else if (e.Error != null)
            {
                MessageBox.Show($"任务执行出错:{e.Error.Message}");
            }
            else
            {
                MessageBox.Show("任务执行完成");
            }
        }
    }
}

注意事项

在实际开发中需要注意以下几点:

  • 所有对UI控件的操作都必须在UI线程执行,跨线程操作需要使用Invoke或者BeginInvoke方法,否则会抛出异常
  • BackgroundWorkerReportProgress方法只有在WorkerReportsProgress设为true时才能调用
  • 取消任务时需要先调用CancelAsync方法,然后在DoWork中检查CancellationPending属性,手动退出循环,不能直接终止线程
  • 进度条的最大值和最小值需要根据实际任务的总量设置,避免进度显示不准确

简化版进度更新实现

如果觉得上面的ProgressChanged事件获取窗体比较复杂,可以调整代码逻辑,把进度条窗体作为主窗体的成员变量,在启动任务时赋值,这样在进度更新时可以直接调用窗体的更新方法:

// 主窗体添加成员变量
private ProgressForm currentProgressForm;

// 修改启动任务的逻辑
private void btnStartTask_Click(object sender, EventArgs e)
{
    if (backgroundWorker.IsBusy)
    {
        MessageBox.Show("当前有任务正在执行,请等待完成或取消后再启动");
        return;
    }
    currentProgressForm = new ProgressForm();
    currentProgressForm.CancelTask += () =>
    {
        if (backgroundWorker.IsBusy)
        {
            backgroundWorker.CancelAsync();
        }
    };
    backgroundWorker.RunWorkerAsync();
    currentProgressForm.ShowDialog();
}

// 修改进度更新逻辑
private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    if (currentProgressForm != null && !currentProgressForm.IsDisposed)
    {
        string message = e.UserState as string;
        currentProgressForm.UpdateProgress(e.ProgressPercentage, message);
    }
}

// 修改任务完成逻辑
private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    currentProgressForm = null;
    if (e.Cancelled)
    {
        MessageBox.Show("任务已取消");
    }
    else if (e.Error != null)
    {
        MessageBox.Show($"任务执行出错:{e.Error.Message}");
    }
    else
    {
        MessageBox.Show("任务执行完成");
    }
}

通过以上步骤,就可以完成一个功能完整的C#进度条窗体,实现异步任务进度的实时显示和任务取消功能,满足大多数桌面应用的进度展示需求。

C#进度条窗体异步任务BackgroundWorker修改时间:2026-07-10 20:18:38

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。