【问题标题】:C# ProgressBar with Deserialize()C# ProgressBar 与 Deserialize()
【发布时间】:2011-03-20 23:14:32
【问题描述】:

我有一些已序列化的大型对象图,其中一些需要一些时间来反序列化。

在这个阶段,我对我的小“请稍候...”框感到非常满意,它会在完成时出现然后消失,但我只是在玩弄一些进度条的想法,以防万一反序列化开始需要更长的时间。

似乎没有任何方法可以获取 BinaryFormatter 对象的内置 Deserialize() 方法的进度。我怀疑如果包含了这样的功能,就会有某种异步回调,每当从流中读取一个字节块时,它就会轮询。

你们中的任何人都见过使用对象序列化/反序列化实现类似 ProgressBar 的行为吗?

【问题讨论】:

  • 对于任何感兴趣的人:我昨天实现了这个并且对结果非常满意。反序列化发生在一个单独的线程中,我假脱机一个额外的进度条线程,它监视流位置/流长度并更新进度条。它工作得很好,并且给出了反序列化进度的相当好的近似值!

标签: c# serialization progress-bar binaryformatter


【解决方案1】:

Stephen Toub 在.NET Matters column of the December 2006 MSDN Magazine 中讨论了解决此问题的方法。

他在流周围实现了一个包装器,然后允许拦截 Read 方法并引发一个合适的事件来表示进度。

【讨论】:

  • 现在是 2015 年,为什么这不是 .NET 4.5 的标准部分?
【解决方案2】:

我之前考虑过这个问题——我能想到的唯一近似方法是包装正在反序列化的 Stream 并在 Formatter 读取它时跟踪位置。然而,这假设 Formatter 在反序列化时线性且连续地读取,并且不能保证它确实如此。

【讨论】:

  • 是的,我也想过这个! :)
【解决方案3】:

不,我没有。但是您可以根据要反序列化的文件的大小来假设反序列化需要多长时间,并将其用于进度条。这可能会为用户提供一些关于所需时间的指示,即使它不准确。

【讨论】:

    【解决方案4】:

    由于我对大图的反序列化进行了一些性能测量,我发现:

    • ISerializable 派生并实现GetObjectData() 可以用作某种“计圈器”,如果您对每种对象类型的调用次数进行估计的话
    • 实现 IDeserializationCallback.OnDeserialization() 根本不可用,因为 OnDeserialization 在加载所有内容后立即调用。

    好吧,因为我也有加载几秒钟的大型对象图,我将尝试使用第一种方法实现一些进度跟踪。如果您想了解进展情况,请联系我。

    至于第一个建议,我不会尝试将其包装成Stream 的某个后代,我宁愿使用另一个线程并检查原始源流LengthPosition 并尝试创造一些进展从此。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-20
      • 2010-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多