2011-09-08 5 views
1

BackgroundWorker을 사용하여 파일을 비동기 적으로 해시하는 Windows Forms 응용 프로그램이 있습니다. 해시중인 각 파일 사이에 CancellationPending을 확인하여 해지를 구현했습니다. 해싱 자체는 본질적으로 이것이다 : 그와백그라운드 스레드에서 큰 파일 해싱

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

유일한 문제는 특히 큰 파일 - 그것은 해당 파일에 대한 완료 취소 될 때까지 해시 연산 블록 - 크기 메가 바이트 또는 기가 바이트의 수백. 예를 들어 모든 N 밀리 초마다 N 바이트 - 파일 해시되는 동안 그 취소를 체크 할 수 있도록

은 무엇이를 수정하는 가장 좋은 방법이 있을까요?

답변

1

ComputeHash 대신 TransformBlock 및 TransformFinalBlock을 사용하여 스트림의 데이터를 해시 알고리즘에 수동으로 펌핑 한 다음 루프에 취소 확인을 삽입하십시오.

1

SHA1은 청크 친화적입니다. 청크로 파일을 읽고 파일이 끝나면 TransformBlock()을 사용한 다음 TransformFinalBlock()을 사용합니다.

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); 
    } 

} 
+0

취소 할 때 예외를 throw하는 것이 좋습니다. 그렇지 않으면 호출자가 파일의 끝 부분을 취소와 혼동 할 수 있습니다. 또한 SHA1이 얼마나 많은 메모리를 차지하고 있는지 알지 못하기 때문에 취소 플래그가 얼마나 중요한지는 알 수 없습니다. –

관련 문제