2016-04-18 9 views
1

私は、この入力コードのMD5ハッシュを計算するこのコードを持っています。filestreamを使用してハッシュ操作を停止します

public static String ComputeMD5(String filename) 
    { 
     using (var md5 = MD5.Create()) 
     { 
      try 
      { 
       using (var stream = File.OpenRead(filename)) 
       { 
        return BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", "").ToLower(); 
       } 
      } 
      catch (Exception) 
      { 
       // File is not accessible, return String.Empty 
       return String.Empty; 
      } 
     } 
    } 

私はこの時間のかかる操作を別のスレッドで実行しています。非常に大きなファイルの場合、この操作には数秒/分かかる場合があります。私がやりたいことは、例えばGUIの "Stop"ボタンを使って、別のスレッドから操作を停止できるようにすることです。助言がありますか?

答えて

1

ファイル部分を読み取り、を各読み取り部分に適用することができます。 (最後の部分はMD5.TransformFinalBlockで読んでください)。 各ブロックを処理する間に、キャンセルが必要かどうかを確認できます。好きな同期プリミティブを自由に使用できます。ここで

はそれがCancellationTokenを使用して、例です。

using System; 
using System.IO; 
using System.Threading; 
using System.Security.Cryptography; 

namespace Stack 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      using (var cancellationTokenSource = new CancellationTokenSource()) 
      { 
       var thread = new Thread(() => 
       { 
        try 
        { 
         var hash = CalcHash("D:/Image.iso", cancellationTokenSource.Token); 
         Console.WriteLine($"Done: hash is {BitConverter.ToString(hash)}"); 
        } 
        catch (OperationCanceledException) 
        { 
         Console.WriteLine("Canceled :("); 
        } 
       }); 
       // Start background thread 
       thread.Start(); 

       Console.WriteLine("Working, press any key to exit"); 
       Console.ReadLine(); 
       cancellationTokenSource.Cancel(); 
      } 

      Console.WriteLine("Finished"); 
      Console.ReadLine(); 
     } 

     static byte[] CalcHash(string path, CancellationToken ct) 
     { 
      using (var stream = File.OpenRead(path)) 
      using (var md5 = MD5.Create()) 
      { 
       const int blockSize = 1024 * 1024 * 4; 
       var buffer = new byte[blockSize]; 
       long offset = 0; 

       while (true) 
       { 
        ct.ThrowIfCancellationRequested(); 
        var read = stream.Read(buffer, 0, blockSize); 
        if (stream.Position == stream.Length) 
        { 
         md5.TransformFinalBlock(buffer, 0, read); 
         break; 
        } 
        offset += md5.TransformBlock(buffer, 0, buffer.Length, buffer, 0); 
        Console.WriteLine($"Processed {offset * 1.0/1024/1024} MB so far"); 
       } 

       return md5.Hash; 
      } 
     } 
    } 
} 
+0

-コロンバ@おかげで、 –

+1

非常に参考に何の問題は、私の答えはあなたの問題を解決しましたか?あなたはそれを閉じることができますか? –

関連する問題