1

总而言之,我有一个昂贵的任务,我使用.NET4.5 下的async/关键字来完成。我通过课程await从后台线程报告进度。Progress<T>

IProgress<T>我作为类型传入的对象是ProgressInfo我作为单例类创建的,以避免在运行期间多次创建和处置这种类型的对象的开销。班级是

public class ProgressInfo : IDisposable
{
    public static ProgressInfo instance = null;
    public WorkbookProgressInfo workbookinfo { get; set; }
    public string progressMessage { get; set; }
    public int progressPercentage { get; set; }

    // Default constructor which has a few overloads 
    // for the class members above.
    protected ProgressInfo()
    {
    }
    ...

    // The default instance creator for the class. 
    // This also has overloads to allow changes to the 
    // class variables.
    public static ProgressInfo Instance()
    {
        if (instance == null)
            instance = new ProgressInfo();
        return instance;
    }
    ...
}

我通过该方法报告进度ReportProgress并将我的设置IProgress<ProgressInfo>

IProgress<CostEngine.ProgressInfo> progressIndicator =
    new Progress<CostEngine.ProgressInfo>(ReportProgress);

来自后台线程的报告通常是使用全局ProgressInfo progressInfo和全局IProgress<ProgressInfo> progressIndicator类似的

...
progressInfo = new ProgressInfo.Instance(workbookinfo, message, n);
progressIndicator.Report(progressInfo);
...

问题是,对于小且执行速度快的运行,ProgressInfo传入的对象在执行时会ReportProgress发生变化ReportProgress,所以我测试

if (progressInfo.workbookinfo != null)
{
    // Do stuff <- here progressInfo.workbookinfo is changing to null!
}

我怎样才能避免这个问题,同时将报告进度的费用保持在最低限度?

谢谢你的时间。

4

1 回答 1

4

您正在尝试在此处优化应用程序的错误部分。

几千个对象对于一个应用程序来说不算什么。创建它们很可能不会成为您的应用程序中的性能问题。但是,可能存在问题的是 UI 的更新。如果在短时间内发生成千上万的进度报告,您将不断更新您的 UI。更新 UI 需要时间,所以如果你遇到瓶颈,它就会在这里。

这里的正确方法是只报告您需要报告的内容。
例如,当您在一分钟内发生 60.000 次迭代并且您报告每一次迭代时,您将尝试每毫秒更新一次 UI 。您的进度条
真的需要1000 FPS吗?我对此表示怀疑。
最好每秒只报告一次。但是,每秒报告一次会产生自己的开销。

我在我的应用程序中所做的是在百分比发生变化时立即报告。
这将导致最多 100 个报告,无论您实际有多少次迭代。
在上面的示例中,我将每 600 次迭代报告一次。

为了简化这一点,我实际上创建了一个名为ProgressReporter.
在其构造函数中,它接受一个创建ProgressInfo对象的工厂委托和总迭代次数。
它提供了ReportProgress您在当前迭代中传递的方法。
该类在内部存储先前报告的百分比,并在调用此方法时计算新的百分比。只有当不同时,它才会使用工厂委托来创建新的并ProgressInfo调用实例。ReportIProgress<T>

顺便说一句:如果您的后台操作不需要几分钟而是几小时,您可以将其更改为不报告百分比何时发生变化,而是百分比的第一个或第二个小数发生变化。
这里的要点是:找到一定数量的报告,每隔几秒就给用户一个反馈。

于 2013-02-08T11:35:33.773 回答