void IssueComputeHash(HashAlgorithms algorithm) { lock (this.computations) { ComputationProgress computation = new ComputationProgress(algorithm); Thread thread = new Thread(AsyncComputeHash); thread.IsBackground = true; thread.Start(computation); this.computations.Add(computation); } }
void AsyncComputeHash(object obj) { ComputationProgress computation = (obj as ComputationProgress); if (computation == null) { return; } lock (this.hashUiElements) this.hashUiElements[computation.Algorithm].SetIsComputing(); // notify UI this.Invoke(new Action(() => { UpdateUiElements(); })); // choose hashing algorithm HashAlgorithm hasher = GetHasher(computation.Algorithm); // save selected file to detect changes during computation string file = this.selectedFile; // initialize stream for status reporting FileStream fileStream = new FileStream(file, FileMode.Open, FileAccess.Read); computation.Stream = new ReportingStream(fileStream); int lastUiUpdate = 0; computation.Stream.ReportPosition += new ReportPositionHandler((sender, newPosition) => { if (computation.Position >= computation.Length || (Environment.TickCount - lastUiUpdate) >= UiUpdateInterval) { lastUiUpdate = Environment.TickCount; UpdateComputationProgress(); } }); // compute and save hash byte[] hash; try { hash = hasher.ComputeHash(computation.Stream); } catch (ObjectDisposedException) { // stream has been closed -> user requested abort return; } finally { //hasher.Dispose(); } lock (this.computations) { computation.Stream.Close(); computation.Stream = null; } lock (this.hashUiElements) { // file has changed? discard the result if (this.selectedFile != file) { return; } this.hashUiElements[computation.Algorithm].SetHash(hash); } // notify UI this.Invoke(new Action(() => { UpdateUiElements(); })); }