【问题标题】:C# - ProgressBar with Marquee styleC# - 带有选取框样式的 ProgressBar
【发布时间】:2015-07-10 12:17:24
【问题描述】:

我想在带有 Marquee 样式的表单上添加一个 ProgressBar,以向用户显示正在进行的操作。在耗时的操作过程中,表单不会更新,因此 ProgressBar 也会“冻结”。

我查看了几篇关于 BackgroundWorker 的帖子,但在我的情况下,操作没有报告进度,这就是我需要 Marquee bar 的原因。

感谢任何帮助或代码 sn-p。

注意:我需要使用 .NET 4.0(支持 XP)所以我不能使用 Task.Run :(

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;

}

【问题讨论】:

  • 您知道在消费过程开始时要完成的迭代次数吗? 在这种情况下,我可能会建议你一些实现
  • 这不是迭代,更像是等待 MySQL 连接或 LDAP 响应。

标签: c# progress-bar


【解决方案1】:

我查看了几篇关于 BackgroundWorker 的帖子,但就我而言 操作不报告进度,这就是我需要 Marquee 栏的原因。

您可以使用 BackgroundWorker,只是不要使用它的“进度”部分。这两件事并不相互排斥...

例子:

    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!");
    }

【讨论】:

  • 听起来不错!是否可以从 bw_RunWorkerCompleted 访问所有表单控件? (那么它是在同一个线程上运行的吗?) button1.Enabled = true; MessageBox.Show("完成!");这表明如此。
  • 是的,您可以安全地访问来自RunWorkerCompleted() 事件的所有控件,因为它已经被BackgroundWorker 控件封送至主UI 线程。 ProgressChanged() 事件也是如此,如果您将来使用它。
【解决方案2】:

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

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

有关Task<> 的更多信息,请参阅https://msdn.microsoft.com/en-us/library/hh195051%28v=vs.110%29.aspx


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

【讨论】:

  • 谢谢,我去看看。请注意,正如我在编辑中提到的那样,我不能使用 Task.Run。 .NET 4.0 是否支持任何替代方案?
【解决方案3】:

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

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;

}

【讨论】:

  • 将点击处理程序保持在这样的轮询循环中通常是一个非常糟糕的想法。
【解决方案4】:

首选解决方案

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 对象,该对象生成一个取消令牌。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-20
    • 1970-01-01
    • 2013-10-29
    • 2017-09-17
    • 1970-01-01
    • 1970-01-01
    • 2010-09-30
    相关资源
    最近更新 更多