我有一个Windows窗体应用程序,使用BackgroundWorker
异步散列文件。我通过在每个被散列的文件之间检查CancellationPending
来实现取消。散列本身就是这样的:
var sha1 = new SHA1CryptoServiceProvider();
byte[] hash = sha1.ComputeHash(
new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
唯一的问题是特别大的文件 - 大小为数百兆字节或千兆字节 - 散列操作会阻止取消,直到该文件完成为止。
修改此内容的最佳方法是什么,以便在对文件进行哈希处理时检查取消 - 例如每 N 毫秒或每个 N 字节?< / p>
答案 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()
。