C# 仅在某些时候向UI报告进度更改

C# 仅在某些时候向UI报告进度更改,c#,C#,假设我有一些UI和一些异步任务处理程序。我可以使用回调方法/事件链接回UI,并告诉它更新其进度显示。这一切都很好 但是,如果我只是想偶尔更改UI的进度,该怎么办?如中所示,每10%,我应该得到一个控制台输出/UI更改,它将告诉我总的/完成的、百分比和经过的时间。这需要一个简单的类: class Progress { int completed; int total; public Progress(int t) { total = t;

假设我有一些UI和一些异步任务处理程序。我可以使用回调方法/事件链接回UI,并告诉它更新其进度显示。这一切都很好

但是,如果我只是想偶尔更改UI的进度,该怎么办?如中所示,每10%,我应该得到一个控制台输出/UI更改,它将告诉我总的/完成的、百分比和经过的时间。这需要一个简单的类:

class Progress
{
    int completed;
    int total;
    public Progress(int t)
    {
        total =  t;
        completed = 0;
    }

    bool ShouldReportProgress()
    {
        if((int)(total/completed) * 100) % 10 == 0)
            return true;
        return false;
    }
}
我需要两件事的帮助:方法“ShouldReportProgress()”很幼稚,由于各种原因(每个步骤输出不止一次,可以完全跳过步骤),因此我希望有更好的方法来实现这一点


我还假设像这样的类肯定已经存在于某个地方。如果没有,我可以自己写,但这似乎是这个问题的一个合乎逻辑的结论。

这里有一个关于如何创建类的想法。我添加了一个字段,用户可以设置该字段来指定
ReportIncrement
,它基本上表示应该报告进度的频率。还有一个
enum
用于
Increment
,它指定
ReportIncrement
是一个固定数字(即每完成15次报告一次)还是一个百分比(即每完成10%报告一次)

每次更改
Completed
字段时,都会调用
ReportProgress
,然后检查是否应实际报告进度(还需要一个参数来强制报告)。检查在
ShouldReport
方法中完成,该方法确定当前进度是否大于或等于上次报告的进度加上增量:

class Progress
{
    public enum Increment
    {
        Percent,
        FixedAmount
    }

    public Increment IncrementType { get; set; }
    public int ReportIncrement { get; set; }
    public int Total { get; }

    private double completed;

    public double Completed
    {
        get { return completed; }
        set
        {
            completed = value;
            ReportProgress();
        }
    }

    public void ReportProgress(bool onlyIfShould = true)
    {
        if (!onlyIfShould || ShouldReport())
        {
            Console.WriteLine(
                $"{Completed / Total * 100:0}% complete ({Completed} / {Total})");
            lastReportedAmount = Completed;
        }
    }

    public Progress(int total)
    {
        Total = total;
    }

    private double lastReportedAmount;

    private bool ShouldReport()
    {
        if (Completed >= Total) return true;

        switch (IncrementType)
        {
            case Increment.FixedAmount:
                return lastReportedAmount + ReportIncrement <= Completed;
            case Increment.Percent:
                return lastReportedAmount / Total * 100 + 
                    ReportIncrement <= Completed / Total * 100;
            default:
                return true;
        }
    }
}

你如何假设x%10等于100?请检查IProgress documentation.FYI,你的示例类没有编译,没有公共成员(构造函数除外)@AndréB如果你需要在UI上调用某个表单,该类/接口是完美的,但它不存储全部/完成的变量,因此,它们最终会出现在处理类中。它也没有代码,只能间歇性地报告,这就是我要寻找的全部要点。不过我可能会尝试扩展/实现它。@RufusL我知道,它实际上只是一个例子。我甚至没有从VS上抄下来,我只是在打字的时候写的。太好了!ShouldReport()switch语句中的这段代码正是我想要弄明白的。增量枚举也是一个好主意。在未来的几年里,有没有什么简单的方法可以将这个类放到一个可以公开访问的地方?我可以储存它,但这不是我的想法。很高兴它有帮助!您可以通过创建新的C#类库项目将其添加到dll中。
private static void Main()
{
    var progress = new Progress(50)
    {
        ReportIncrement = 10,
        IncrementType = Progress.Increment.Percent
    };

    Console.WriteLine("Starting");

    for (int i = 0; i < progress.Total; i++)
    {
        Console.Write('.');
        Thread.Sleep(100);

        progress.Completed++;
    }

    Console.WriteLine("\nDone!\nPress any key to exit...");
    Console.ReadKey();
}
// Same code as above, only this time we specify 'FixedAmount'
var progress = new Progress(50)
{
    ReportIncrement = 10,
    IncrementType = Progress.Increment.FixedAmount
};