public Dictionary<string, DataHash> ThreadyDigestFiles(IEnumerable<string> files, bool stopOnUnCachable)
{
lock (includeCache)
{
var fcount = files.Count();
var rv = new Dictionary<string, DataHash>();
var threadcount = HashingThreadCount;
if ((threadcount < 2) || (fcount < threadcount))
{
Logging.Emit("st hash {0} files", fcount);
foreach (var f in files)
{
var d = DigestSourceFile(f);
rv[f.ToLower()] = d;
if (d.Result != DataHashResult.Ok) break;
}
}
else
{
Logging.Emit("mt hash {0} files on {1} threads", fcount, threadcount);
var fa = files.ToArray();
var tl = new List<Thread>();
var taken = 0;
var chunk = (1 + fcount / (threadcount));
if (chunk < 1) chunk = 1;
var inputs = new List<ThreadyDigestInput>();
do
{
var input = new ThreadyDigestInput()
{
files = fa,
results = new List<DataHash>(),
provider = new MD5CryptoServiceProvider(),
begin = taken,
chunksize = chunk,
stopOnCachable = stopOnUnCachable,
};
var t = new Thread(ThreadyDigestWorker);
taken += chunk;
t.Start(input);
inputs.Add(input);
tl.Add(t);
} while (taken < fcount);
for (var i = 0; i < tl.Count; i++)
{
var t = tl[i];
t.Join(); // thread finished, store it's results
foreach (var h in inputs[i].results)
{
rv[h.InputName.ToLower()] = h;
}
}
}
return rv;
}
}