如何从其他类更新进度条?

7

我有一个用C#编写的命令行工具(我有源代码),现在想在Visual Studio 2010中为其制作GUI。在GUI中,我想更新进度条以反映工具操作的进度。如何从工具内部发出信号表明已经取得进展并更新进度条呢?以下是我正在做的一些简化示例代码。

private void doThings_Click(object sender, EventArgs e)
{
  myToolInstance.doWorkThatNeedsToReportProgress();
}

这个工具正在执行一系列函数调用,通常大约有30个。我希望在每个函数完成时更新进度条。


1
你是否掌控命令行工具的源代码?该工具目前是否以任何方式指示进度?如何指示? - Eric J.
进展取决于你试图完成的事情。您需要找到一个反映手头任务的变量,可以监视和更新到进度条中。如果您编辑帖子并提供具体信息,将会更有帮助。 - Ari
你能提供一些代码,并指出哪个部分需要进度条吗?此外,你是在哪个框架中构建你的GUI(WPF,Winforms?)? - EtherDragon
你是如何实例化你的工具的? - Mark Hall
UI - Forms 还是 WPF?为什么命令行工具需要保留?难道你不能把它全部移到 UI 中吗?毕竟它们都是 .NET 和 C#。 - paparazzo
2个回答

17
在包含进度条的表单中创建一个公共属性或公共方法。
public void SetProgress(int progress)
{
    progressBar.Progress = progress;
}

现在你可以使用下面的代码更新进度条:

myForm.SetProgress(50);

另一种方法是在某处具有 ProgressChanged 事件,并让表单订阅此事件。

public class Tool {
    public event Action<int> ProgressChanged;

    private void OnProgressChanged(int progress) 
    {
        ProgressChanged?.Invoke(progress);
    }

    public void DoSomething()
    {
        ...
        OnProgressChanged(30);
        ...
    }
}
在表单中你会有类似这样的内容。
private Tool _tool;

public MyForm () // Constructor of your form
{
    _tool = new Tool();
    _tool.ProgressChanged += Tool_ProgressChanged;
}

private void Tool_ProgressChanged(int progress)
{
    progressBar.Progress = progress;
}

问题在于进度数据来自外部工具(在不同的进程中运行)。 - Eric J.
但它能够工作是因为我可以(并且已经)获取了该工具的源代码。 - Whyrusleeping

0

虽然我不是黄铲候选人,但我遇到了类似的问题,我想在这里分享我的解决方案。

一般来说,我有一个由于计算复杂性而将以异步方式运行的方法。其中一个输入参数就是进度条本身。
由于 ProgressBar 是可空类型,在调用该方法时不是必需的。
在方法内部,我使用其分派程序推进进度条 - 在许多情况下,该方法将在拥有进度条的其他线程上运行。为了处理进度条的空值可能性,我使用了 nullable 运算符:

private string MyMethod(int input, ProgressBar progressBar)
{
    while(!done)
    {
        // Do the hard work.

        progressBar?.Dispatcher.Invoke(() => progressBar.Value++);
    }
}

现在,我需要在调用方法之前设置进度条最大值,并且它必须设置为预期长度。

有些人可能会说,每次需要推进进度条时都调用调度程序会导致极大的低效率。是的,我同意这一点,但这完全取决于我们需要经历多少步骤。这就是为什么我进行了一些快速基准测试。

对于我的情况,我有超过300,000(三十万)个步骤(每个步骤都是将一些数据格式化为字符串并将该字符串写入文件)。运行没有更新进度条的方法是我的参考。

  • 每一步更新进度条使运行时间增加了2,000%以上(长了二十倍)
  • 每10步更新进度条使运行时间增加了250%以上(长了两倍半)
  • 每100步更新进度条使运行时间增加了约15%(长了约1/8)
  • 每1000步更新进度条使运行时间增加了约3%(微小差异)

由于我的进度条宽度为240像素,我已经将进度条最大值设定为300,并相应地进行更新,以获得非常平滑的动画效果,而不会有明显的性能损失。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接