【问题标题】:VS Progress bar, what to do when 100%VS进度条,100%的时候怎么办
【发布时间】:2015-10-14 10:30:03
【问题描述】:

这是我今天必须的代码。问题是进度条在 1 秒内从 0 变为 30%。

    private void pictureBox1_Click(object sender, EventArgs e)
    {
        progressBar1.Value = 5;

        System.Diagnostics.Process.Start("c:/installer.exe").WaitForExit();
        progressBar1.Value = 10;


        System.Diagnostics.Process.Start("c:/installer2.exe");
    progressBar1.Value = 30;

 }
    }

我想在进度条1(´s)之后添加“睡眠”或“等待”

附言。我只想澄清一件事,我在 Visual Studio 中编码的级别为 0。我昨天开始这样做了。

【问题讨论】:

  • 这是 C# 代码。你确定你在编写 C++/CLI 代码吗?

标签: c# visual-studio


【解决方案1】:

几年前,您必须创建一个 BackgroundWorker 对象来完成这项工作以保持您的 UI 响应。

几年前我们就有了 async-await 可以完成这项工作。 async-await 函数看起来像同步代码,但每当它看到 await 时,代码就会停止,直到它等待的任务完成。同时,等待的线程有时间做其他事情,比如更新进度条,或保持 UI 响应。一旦线程等待的任务完成,线程将继续执行等待之后的语句。

要使用 async-await,您唯一要做的就是声明您的事件处理程序异步。完成后,您可以调用其他异步函数并等待它们的结果。

在您开始您的流程后,您可以等待 Task.Delay(TimeSpan)。在这个方法中,主线程没有做任何事情,所以它有时间做其他 UI 工作。延迟结束后,可以更新进度条,查看进程是否结束。

using System.Diagnostics;
private async void pictureBox1_Click(object sender, EventArgs e)
{
    // start the progress, don't wait until finished yet:
    var process1 = Process.Start("c:/installer.exe").WaitForExit();
    while (!process1.HasExited)
    {
        // process not finished yet, increase progress bar and wait a while
        this.progressBar1.Step();
        await Task.Delay(TimeSpan.FromSeconds(0.2);
    }

    // if here, process1 has finished: we are halfway:
    progressBar1.Value = (progressbar1.Minimum + progressBar1.Maximum)/2;

    // start process 2
    var process2 = Process.Start("c:/installer2.exe");
     while (!process2.HasExited)
    {
        // process not finished yet, increase progress bar and wait a while
        this.progressBar1.Step();
        await Task.Delay(TimeSpan.FromSeconds(0.2);
    }
    // both processes finished; full progressbar:
    this.progressBar1.Value = this.progressBar1.Maximum;
}

当然,您可能会遇到安装需要很长时间的问题。如果值变得太高,请考虑不再更新进度条

var halfWay = (progressbar1.Minimum + progressBar1.Maximum)/2;
while (!process1.HasExited)
{
    if (this.progressBar1.Value < halfWay)
        this.progressBar1.Step();
    ...
}

请注意,异步等待是由一个线程完成的。它不是多任务处理。 Eric Lippert 对 stackoverflow 有一个很好的类比: async/await - Is this understanding correct?

假设你必须做早餐。烤一些面包,煮一些鸡蛋。

  • 同步:开始烤面包。等到烘烤结束。开始煮鸡蛋,等鸡蛋煮熟。
  • 异步但非并发:开始烤面包,烤面包时开始煮鸡蛋。在煮鸡蛋的同时,您还可以做其他事情,例如泡茶。过了一会儿,你等到鸡蛋煮熟,然后等到面包烤好。这通常是异步等待。
  • 异步和并发:雇一个厨师烤面包,雇一个厨师煮鸡蛋,等到两个厨师都吃完。在这里,烘烤和烹饪是由不同的线程完成的。这是最昂贵的方法

【讨论】:

  • 我在“步骤”部分出错了。不可调用的成员 'progressbar.setp' 不能像方法一样使用
  • 我的,你看了多少秒的 MSDN 定义的 System.Windows.Forms.ProgressBar?我显然犯了一个错误,因为我必须把所有的东西都记下来。 MSDN 说: Step 是“每次调用 PerformStep 方法时增加进度条的数量”。我认为这足以让您更正代码。或者使用:值 += 1;
【解决方案2】:

使用代码

System.Threading.Thread.Sleep(5000);

这将使当前线程保持 5 秒。

但是:这不会改变您当前的问题。

如果我是你,我会调查backgroundworker。这有点棘手,但它可以严重帮助你。您当前的线程得到更新,而后台工作线程可以停止。因此,您会收到一个不错的表单,其中值 get 已更新。在当前线程中也不鼓励使用 Sleep 函数。

【讨论】:

  • 请注意,BackgroundWorkers 有点被 Tasks 所取代,使用起来要容易得多。
  • 现在调查 :-) @RoyT.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-30
相关资源
最近更新 更多