From bab6d4a0a8e17eba3d66dc7c9f62cbf375fcc0f5 Mon Sep 17 00:00:00 2001 From: Sergii Gulyk Date: Sat, 6 May 2023 21:22:58 +0200 Subject: [PATCH] MD5 implementation is not thread safe. As a result ChangeId sometimes got same value for different observations under heavy multi-threaded test. Made it thread-safe without blocking thread, but sacrificed some memory. --- .../Extensions/StringFunctions.cs | 43 +++++++++++++++---- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/src/MTConnect.NET-Common/Extensions/StringFunctions.cs b/src/MTConnect.NET-Common/Extensions/StringFunctions.cs index fa996f96..b053028f 100644 --- a/src/MTConnect.NET-Common/Extensions/StringFunctions.cs +++ b/src/MTConnect.NET-Common/Extensions/StringFunctions.cs @@ -12,10 +12,38 @@ namespace MTConnect { public static class StringFunctions { - private static readonly Random _random = new Random(); private static readonly Encoding _utf8 = Encoding.UTF8; - private static MD5 _md5 = MD5.Create(); + [ThreadStatic] + private static MD5 _md5; + + [ThreadStatic] + private static Random _random; + + private static MD5 MD5Algorithm + { + get + { + if (_md5 == null) + { + _md5 = MD5.Create(); + } + return _md5; + } + } + + private static Random Random + { + get + { + if (_random == null) + { + _random = new Random(); + } + + return _random; + } + } public static string ToPascalCase(this string s) { @@ -237,7 +265,7 @@ public static string RandomString(int length) { const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; return new string(Enumerable.Repeat(chars, length) - .Select(s => s[_random.Next(s.Length)]).ToArray()); + .Select(s => s[Random.Next(s.Length)]).ToArray()); } public static DateTime ToDateTime(this string s) @@ -254,8 +282,7 @@ public static string ToMD5Hash(this string s) { try { - if (_md5 == null) _md5 = MD5.Create(); - var hash = _md5.ComputeHash(_utf8.GetBytes(s)); + var hash = MD5Algorithm.ComputeHash(_utf8.GetBytes(s)); return string.Concat(hash.Select(b => b.ToString("x2"))); } catch { } @@ -269,7 +296,7 @@ public static string ToMD5Hash(this byte[] bytes) { try { - var hash = _md5.ComputeHash(bytes); + var hash = MD5Algorithm.ComputeHash(bytes); return string.Concat(hash.Select(b => b.ToString("x2"))); } catch { } @@ -296,7 +323,7 @@ public static byte[] ToMD5HashBytes(this string s) { try { - return _md5.ComputeHash(_utf8.GetBytes(s)); + return MD5Algorithm.ComputeHash(_utf8.GetBytes(s)); } catch { } @@ -309,7 +336,7 @@ public static byte[] ToMD5HashBytes(this byte[] bytes) { try { - return _md5.ComputeHash(bytes); + return MD5Algorithm.ComputeHash(bytes); } catch { } }