C# - 带有Marquee样式的ProgressBar

时间:2015-07-10 12:17:25

标签: c# progress-bar

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

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

感谢任何帮助或代码段。

注意:我需要使用.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;

}

4 个答案:

答案 0 :(得分:8)

  

我查了几篇关于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!");
    }

答案 1 :(得分:0)

你仍然需要在不同的线程上运行耗时的工作......你在UI线程上运行它意味着UI没有机会进行任何UI更新(因此你见证了冻结)! / p>

您应该考虑使用# Root logger option log4j.rootLogger=DEBUG, stdout, file # Redirect log messages to console log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.out log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n # Redirect log messages to a log file, support file rolling. log4j.appender.file=org.apache.log4j.RollingFileAppender log4j.appender.file.File=logs/log4j-MyFirstClass.log log4j.appender.file.MaxFileSize=5MB log4j.appender.file.MaxBackupIndex=10 log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n 代替Task<>

有关BackgroundWorker的详细信息,请参阅https://msdn.microsoft.com/en-us/library/hh195051%28v=vs.110%29.aspx

如果您无法使用Task<>,则应恢复为Task<>并使用BackgroundWorker事件停止选取框并将程序移至下一个操作。

答案 2 :(得分:0)

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

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;

}

答案 3 :(得分:0)

首选解决方案

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());
}

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