Hej
Miałbym do Was pytanie. Używam sobie w swojej aplikacji kilku funkcji skrótu (sha1, md5, crc32, sha256, sha384, sha512) które obliczam dla danego pliku. Pliki są zazwyczaj dość dużych rozmiarów(powyżej 1GB). Pomyślałem, że używając wątki można nieco przyśpieszyć ich liczenie. Znalazłem wcześniej program HashMyFiles napisany prawdopodobnie w C++ więc w sumie mógł mi się przydać i tak wcześniej obliczałem te skróty. Zależało mi natomiast na możliwości monitorowania aktualnego postępu dla pliku przy liczeniu tych hashy. W tym momencie mój kawałek kodu wygląda następująco:
public static string[] Checksums(FileStream fileStream)
{
int percentOfDone = 0, lastPercentOfDone = 0;
sha256 = new SHA256Managed();
sha512 = new SHA512Managed();
sha384 = new SHA384Managed();
md5 = MD5.Create();
sha1 = new SHA1Managed();
crc32 = new CRC32();
byte[] buff = new byte[BufferLength];
b1 = new byte[BufferLength];
b2 = new byte[BufferLength];
Thread t1 = null;
Thread t2 = null;
while (fileStream.Length - fileStream.Position > BufferLength)
{
OnEvent(new BlockCountEventArgs((int)(fileStream.Position * 100 / fileStream.Length)));
fileStream.Read(buff, 0, BufferLength);
if (t1 != null)
t1.Join();
if (t2 != null)
t2.Join();
buff.CopyTo(b1, 0);
t1 = new Thread(new ThreadStart(() => {
sha256.TransformBlock(HashesCalculator.b1, 0, BufferLength, null, 0);
sha512.TransformBlock(HashesCalculator.b1, 0, BufferLength, null, 0);
crc32.TransformBlock(HashesCalculator.b1, 0, BufferLength, null, 0);
}));
t1.Start();
buff.CopyTo(b2, 0);
t2 = new Thread(new ThreadStart(() =>
{
sha1.TransformBlock(HashesCalculator.b2, 0, BufferLength, null, 0);
sha384.TransformBlock(HashesCalculator.b2, 0, BufferLength, null, 0);
}));
t2.Start();
md5.TransformBlock(buff, 0, BufferLength, null, 0);
}
if (t1 != null)
t1.Join();
if (t2 != null)
t2.Join();
int last = fileStream.Read(buff, 0, BufferLength);
sha256.TransformFinalBlock(buff, 0, last);
sha512.TransformFinalBlock(buff, 0, last);
sha384.TransformFinalBlock(buff, 0, last);
md5.TransformFinalBlock(buff, 0, last);
sha1.TransformFinalBlock(buff, 0, last);
crc32.TransformFinalBlock(buff, 0, last);
lastPercentOfDone = (int)((fileStream.Position * 100 / fileStream.Length));
if (percentOfDone != lastPercentOfDone)
{
OnEvent(new BlockCountEventArgs(lastPercentOfDone));
percentOfDone = last;
}
b1 = null;
b2 = null;
string[] r = new string[]{
BytesToStr(md5.Hash),
BytesToStr(sha1.Hash),
BytesToStr(crc32.Hash.Reverse().ToArray()),
BytesToStr(sha256.Hash),
BytesToStr(sha512.Hash),
BytesToStr(sha384.Hash)
};
sha1.Dispose();
sha256.Dispose();
sha384.Dispose();
sha512.Dispose();
crc32.Dispose();
md5.Dispose();
return r;
}
Jak mógłbym przyśpieszyć i zoptymalizować ten kawałek kodu, ponieważ jest on dość niestabilny i przy okazji sporo zapycha mi procesor.