进度条- c# -带有选框样式的进度条

本文关键字:样式 | 更新日期: 2023-09-27 18:02:09

我想添加一个窗体上的选框样式的进度条,以显示用户的东西正在进行中。在耗时的操作中,表单不会得到更新,因此进度条也会"冻结"。

我已经检查了几个关于BackgroundWorker的帖子,但在我的情况下,操作不报告进度,这就是为什么我需要一个选框栏。

感谢任何帮助或代码片段。

注意:我需要使用。net 4.0(为XP支持),所以我不能使用任务。:运行(

button1_Click(object sender, EventArgs e)
{
    progressBar1.Style = ProgressBarStyle.Marquee;
    progressBar1.MarqueeAnimationSpeed = 50;
    // INSERT TIME CONSUMING OPERATIONS HERE
    // THAT DON'T REPORT PROGRESS
    Thread.Sleep(10000);
    progressBar1.MarqueeAnimationSpeed = 0;
    progressBar1.Style = ProgressBarStyle.Blocks;
    progressBar1.Value = progressBar1.Minimum;
}

进度条- c# -带有选框样式的进度条

我已经检查了几个关于BackgroundWorker的帖子,但在我的情况下操作不报告进度,这就是为什么我需要一个选框栏。

你可以使用BackgroundWorker,只是不要使用它的"progress"部分。这两件事并不相互排斥……

的例子:

    private void button1_Click(object sender, EventArgs e)
    {
        button1.Enabled = false;
        progressBar1.Style = ProgressBarStyle.Marquee;
        progressBar1.MarqueeAnimationSpeed = 50;
        BackgroundWorker bw = new BackgroundWorker();
        bw.DoWork += bw_DoWork;
        bw.RunWorkerCompleted += bw_RunWorkerCompleted;
        bw.RunWorkerAsync();
    }
    void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        // INSERT TIME CONSUMING OPERATIONS HERE
        // THAT DON'T REPORT PROGRESS
        Thread.Sleep(10000);
    }
    void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        progressBar1.MarqueeAnimationSpeed = 0;
        progressBar1.Style = ProgressBarStyle.Blocks;
        progressBar1.Value = progressBar1.Minimum;
        button1.Enabled = true;
        MessageBox.Show("Done!");
    }

您仍然需要在不同的线程上运行您耗时的工作…你在UI线程上运行它,这意味着UI没有机会进行任何UI更新(因此你会看到冻结)!

你应该考虑使用Task<>而不是BackgroundWorker

参见https://msdn.microsoft.com/en-us/library/hh195051%28v=vs.110%29.aspx获取Task<>的更多信息。


如果你不能使用Task<>,那么你应该恢复到BackgroundWorker,并使用WorkCompleted事件来停止选框,并将你的程序移动到下一个操作。

解决。然而,我认为这是最不优雅的处理方式。

button1_Click(object sender, EventArgs e)
{
    progressBar1.Style = ProgressBarStyle.Marquee;
    progressBar1.MarqueeAnimationSpeed = 50;

    Task task = Task.Factory.StartNew(() =>
    {
        // INSERT TIME CONSUMING OPERATIONS HERE
        // THAT DON'T REPORT PROGRESS
        Thread.Sleep(10000);
    });
    while (!task.IsCompleted)
    {
         Application.DoEvents();
         Thread.Sleep(1);
    }
    progressBar1.MarqueeAnimationSpeed = 0;
    progressBar1.Style = ProgressBarStyle.Blocks;
    progressBar1.Value = progressBar1.Minimum;
}

首选解决方案

private void button1_Click(object sender, EventArgs e)
{
    button1.Enabled = false;
    progressBar1.Style = ProgressBarStyle.Marquee;
    progressBar1.MarqueeAnimationSpeed = 50;
    Task.Factory.StartNew(() => {
           // INSERT TIME CONSUMING OPERATIONS HERE
           // THAT DON'T REPORT PROGRESS
           Thread.Sleep(10000);
        }, TaskCreationOptions.LongRunning).
            ContinueWith(t => {
                progressBar1.MarqueeAnimationSpeed = 0;
                progressBar1.Style = ProgressBarStyle.Blocks;
                progressBar1.Value = progressBar1.Minimum;
                button1.Enabled = true;
                MessageBox.Show("Done!");
            }, TaskScheduler.FromCurrentSynchronizationContext());
}

注:为了处理可能的操作取消,示例实例化了一个CancellationTokenSource对象,该对象生成一个取消令牌。