【发布时间】:2013-01-24 03:17:16
【问题描述】:
所有,我有一个昂贵的任务,我使用 .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);
...
问题在于,对于小型且快速执行的运行,传递给ReportProgress 的ProgressInfo 对象会随着ReportProgress 的执行而变化,因此我进行了测试
if (progressInfo.workbookinfo != null)
{
// Do stuff <- here progressInfo.workbookinfo is changing to null!
}
如何避免此问题,同时将报告进度的费用降到最低?
感谢您的宝贵时间。
【问题讨论】:
-
在这种情况下使用单例似乎非常非常奇怪。对于初学者,您的
ProgressInfo类不是线程安全的。我不会那样做,你也不应该这样做。您是否真的验证过ProgressInfo实例的创建是一个性能问题?还是您只是认为可能是一个? -
我只是认为它可能是一个。我正在从大型嵌套循环中报告并创建这些(尽管相当轻量级)对象数千次(取决于运行)似乎是我可以通过使用单例来避免的开销......我也不确定事实如何
Progressinfo不是线程安全的,这对这个问题有任何影响,因为同步上下文在使用IProgress<T>时得到了完全处理。感谢您的宝贵时间。 -
非常糟糕的主意。通过尝试使此类具有所有锁定等线程安全性,您将产生更大的开销。您在这里所做的是过早的优化。没有什么好东西来自它。使用分析器优化您已验证为问题的内容。
-
workbookinfo更改为null的事实很好地证明了您的类不是线程安全的。同步上下文与此无关。 -
每次都创建 ProgressInfo,不要使用单音。要提高性能,只需尝试减少进度通知次数
标签: c# multithreading .net-4.5 async-await progress