值得知道KeyedHashAlgorithm.ComputeHash() 不是线程安全的,因为它为相同的KeyedHashAlgorithm.Key 提供了不确定的结果。
在我的例子中,我想缓存 KeyedHashAlgorithm,因为我的 KeyedHashAlgorithm.Key 总是相同的,以从客户端验证 真实性。我意识到ComputeHash() 不一致,可能它会将内部变量缓存到KeyedHashAlgorithm 实例中。我应该缓存每个线程ThreadStatic 或ThreadLocal 的实例。这是测试:
静态KeyedHashAlgorithm 给出不一致的结果:
var kha = KeyedHashAlgorithm.Create("HMACSHA256");
kha.Key = Encoding.UTF8.GetBytes("key");
Action comp = () =>
{
var computed = kha.ComputeHash(Encoding.UTF8.GetBytes("message"));
Console.WriteLine(Convert.ToBase64String(computed));
};
Parallel.Invoke(comp, comp, comp, comp, comp, comp, comp, comp);
与每个线程的KeyedHashAlgorithm 相比:
ThreadLocal<KeyedHashAlgorithm> tl= new ThreadLocal<KeyedHashAlgorithm>(() =>
{
var kha = KeyedHashAlgorithm.Create("HMACSHA256");
kha.Key = Encoding.UTF8.GetBytes("key");
return kha;
});
Action comp = () =>
{
var computed = tl.Value.ComputeHash(Encoding.UTF8.GetBytes("message"));
Console.WriteLine(Convert.ToBase64String(computed));
};
Parallel.Invoke(comp, comp, comp, comp, comp, comp, comp, comp);
此代码可用于测试其他函数的“线程安全”结果。希望这对其他人有帮助。