在后台线程上散列大文件

时间:2011-09-08 00:56:57

标签: c# .net winforms backgroundworker hash

我有一个Windows窗体应用程序,使用BackgroundWorker异步散列文件。我通过在每个被散列的文件之间检查CancellationPending来实现取消。散列本身就是这样的:

var sha1 = new SHA1CryptoServiceProvider();
byte[] hash = sha1.ComputeHash(
    new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));

唯一的问题是特别大的文件 - 大小为数百兆字节或千兆字节 - 散列操作会阻止取消,直到该文件完成为止。

修改此内容的最佳方法是什么,以便在对文件进行哈希处理时检查取消 - 例如每 N 毫秒或每个 N 字节?< / p>

3 个答案:

答案 0 :(得分:2)

您可以创建自己的可取消流,并将其作为散列函数的输入。这些方面的东西:

class CancellableFileStream : FileStream {

  readonly BackgroundWorker backgroundWorker;

  public CancellableFileStream(BackgroundWorker backgroundWorker, String path, FileMode mode, FileAccess access, FileShare share)
    : base(path, mode, access, share) {
    this.backgroundWorker = backgroundWorker;
  }

  public override Int32 Read(Byte[] array, Int32 offset, Int32 count) {
    if (this.backgroundWorker.CancellationPending)
      return 0;
    return base.Read(array, offset, count);
  }

}

答案 1 :(得分:1)

使用TransformBlock和TransformFinalBlock而不是ComputeHash,手动将数据从流中抽取到哈希算法 - 然后在循环中插入取消检查。

答案 2 :(得分:1)

SHA1非常友好。按块读取文件,使用TransformBlock(),然后在文件结束时使用TransformFinalBlock()