Многопоточный геттер System.IndexOutOfRangeException - C#
Формулировка задачи:
Есть такой код, так вот не могу понять почему в переменную next, которая используется как счетчик проскакивает число больше массива байтов, когда по идее запрос значения next должен пройти через геттер функцию и там в данном случае попасть в цикл, пока значение next не станет меньше размера массива байтов, но периодически 2 - 3 параллельно работающих потока с первым потоком (поток, который запускает поток Seed(0) и переходит в ожидание завершения запущенного потока) не останавливаясь в геттере забирают значение переменной next больше размера массива.
public static class Random { // 4 Mb Random bytes buffer private static byte[] seedArr = new byte[4194304]; private static Thread waiter; private static long _next; private static long next { get { if (_next >= seedArr.LongLength && waiter == null) { waiter = new Thread(() => Seed(0)); waiter.Start(); waiter.Join(); waiter = null; _next = 0; } while (_next >= seedArr.LongLength) { if (waiter != null && waiter.ThreadState == ThreadState.Running) { waiter.Join(); } Thread.SpinWait(1); } return _next; } set { _next = value; } } public static void Seed(ulong Seed) { if (Seed.GetType() != typeof(ulong) || Seed <= 0) { RNGCryptoServiceProvider CSP = new RNGCryptoServiceProvider(); byte[] bytes = new byte[8]; CSP.GetNonZeroBytes(bytes); CSP.Dispose(); Seed = BitConverter.ToUInt64(bytes, 0); } { ulong[] ticks = new ulong[4] { ulong.MaxValue, Convert.ToUInt64(DateTime.UtcNow.Ticks), Convert.ToUInt64(Environment.TickCount), Convert.ToUInt64(Thread.CurrentThread.ManagedThreadId) }; ulong[] modules_a = new ulong[4] { ticks[0] / ticks[1], ticks[0] % ticks[1], ticks[0] / ticks[2], ticks[0] % ticks[2] }; byte[] bytes = new byte[8]; { byte[] bytes_t = new byte[524288]; { byte[] sbytes = BitConverter.GetBytes(Seed); MemoryStream bytebuff = new MemoryStream(); bytebuff.Write(sbytes, 0, sbytes.Length); Extensions.ParallelFor(1, 4, i => { byte[] tbytes = BitConverter.GetBytes(ticks[i]); lock (bytebuff) { bytebuff.Write(tbytes, 0, tbytes.Length); } }); Extensions.ParallelFor(0, 4, i => { byte[] mbytes = BitConverter.GetBytes(modules_a[i]); lock (bytebuff) { bytebuff.Write(mbytes, 0 , mbytes.Length); } }); byte[] seedb = bytebuff.ToArray(); bytebuff.Dispose(); { byte[] rseedb = seedb; rseedb.Reverse(); int sl = seedb.Length, rsl = rseedb.Length; MemoryStream buff = new MemoryStream(); buff.Write(seedb, 0, sl); buff.Write(rseedb, 0, rsl); for (int i = 0; i < 2; i++) { rseedb = buff.ToArray(); buff.Write(rseedb, 0, rseedb.Length); } seedb = buff.ToArray(); buff.Dispose(); } RNGCryptoServiceProvider CSP = new RNGCryptoServiceProvider(); HMACMD5 hmacmd5 = new HMACMD5(seedb); HMACSHA512 hmacsha512 = new HMACSHA512(seedb); CSP.GetNonZeroBytes(bytes_t); byte[] md5 = hmacmd5.ComputeHash(bytes_t, 0, bytes_t.Length), sha512 = hmacsha512.ComputeHash(bytes_t, 0, bytes_t.Length); CSP.Dispose(); hmacmd5.Dispose(); hmacsha512.Dispose(); long md5l = md5.LongLength, sha512l = sha512.LongLength; // for (int i = 0, l = bytes_t.Length, pos = 0; i < l; i++) Extensions.ParallelFor(0, bytes_t.LongLength, i => { long posmd5 = i % md5l, possha512 = i % sha512l; bytes_t[i] ^= md5[posmd5]; bytes_t[i] ^= sha512[possha512]; }); md5 = null; sha512 = null; } Extensions.ParallelFor(0, bytes_t.LongLength, i => { long pos = i % 8; lock (bytes) { bytes[pos] ^= bytes_t[i]; } }); bytes_t = null; } ulong modules = Convert.ToUInt64(Seed) ^ BitConverter.ToUInt64(bytes, 0), modules_x = 0, modules_t = 0, modules_xt = 0; modules_x = modules_a[0] ^ modules_a[1] ^ modules_a[2] ^ modules_a[3]; modules_t = modules_x >> 1; modules_t = modules_x % modules_t; modules_t = modules_x ^ modules_t; ticks[1] ^= ticks[3]; modules_xt = ticks[1] % modules_t; modules = modules ^ modules_t ^ modules_xt; Seed = modules; } { RNGCryptoServiceProvider CSP = new RNGCryptoServiceProvider(); CSP.GetNonZeroBytes(seedArr); CSP.Dispose(); byte[] bytes = BitConverter.GetBytes(Seed); Extensions.ParallelFor(0, seedArr.LongLength, i => { long pos = i % 8; lock (seedArr) { seedArr[i] ^= bytes[pos]; } }); } Seed = 0; } private static byte GetByte() { byte retbyte; retbyte = seedArr[next]; // Здесь System.IndexOutOfRangeException next++; return retbyte; } public static byte[] NextBytes(ulong count = 1) { byte[] bytes = new byte[count]; // for (int i = 0; i < count; i++) Extensions.ParallelFor(0, bytes.LongLength, i => { byte lbyte = GetByte(); bytes[i] = lbyte; }); return bytes; } }
Решение задачи: «Многопоточный геттер System.IndexOutOfRangeException»
textual
Листинг программы
Timer frequency as ticks per microsecond: 2343835000000 Timer is high-resolution: True Max parallel threads pass: 4 Serial 1Mb byte array, microseconds: 1375 Parallel 1Mb byte array, microseconds: 3253 Serial 2Mb byte array, microseconds: 2799 Parallel 2Mb byte array, microseconds: 7084 Serial 10Mb byte array, microseconds: 14196 Parallel 10Mb byte array, microseconds: 33382 Serial 18Mb byte array, microseconds: 25609 Parallel 18Mb byte array, microseconds: 61043 Serial 26Mb byte array, microseconds: 36987 Parallel 26Mb byte array, microseconds: 85168 Serial 34Mb byte array, microseconds: 48284 Parallel 34Mb byte array, microseconds: 113083 Serial 42Mb byte array, microseconds: 59928 Parallel 42Mb byte array, microseconds: 140026 Serial 50Mb byte array, microseconds: 71676 Parallel 50Mb byte array, microseconds: 166940 Serial 58Mb byte array, microseconds: 84363 Parallel 58Mb byte array, microseconds: 194119 Serial 66Mb byte array, microseconds: 94159 Parallel 66Mb byte array, microseconds: 220923 Serial 74Mb byte array, microseconds: 105542 Parallel 74Mb byte array, microseconds: 244599 Serial 82Mb byte array, microseconds: 116878 Parallel 82Mb byte array, microseconds: 277487 Serial 90Mb byte array, microseconds: 128088 Parallel 90Mb byte array, microseconds: 297518 Serial 98Mb byte array, microseconds: 139974 Parallel 98Mb byte array, microseconds: 330158 Serial 106Mb byte array, microseconds: 151253 Parallel 106Mb byte array, microseconds: 356841 Serial 114Mb byte array, microseconds: 161735 Parallel 114Mb byte array, microseconds: 396256 Serial 122Mb byte array, microseconds: 173373 Parallel 122Mb byte array, microseconds: 413497 Serial 130Mb byte array, microseconds: 185386 Parallel 130Mb byte array, microseconds: 439991 Serial 138Mb byte array, microseconds: 197546 Parallel 138Mb byte array, microseconds: 464581 Serial 146Mb byte array, microseconds: 209185 Parallel 146Mb byte array, microseconds: 501030 Serial 154Mb byte array, microseconds: 220108 Parallel 154Mb byte array, microseconds: 535607 Serial 162Mb byte array, microseconds: 232093 Parallel 162Mb byte array, microseconds: 559694 Serial 170Mb byte array, microseconds: 242831 Parallel 170Mb byte array, microseconds: 592954 Serial 178Mb byte array, microseconds: 255106 Parallel 178Mb byte array, microseconds: 630598 Serial 186Mb byte array, microseconds: 272178 Parallel 186Mb byte array, microseconds: 797705 Serial 194Mb byte array, microseconds: 275468 Parallel 194Mb byte array, microseconds: 782837 Serial 202Mb byte array, microseconds: 286021 Parallel 202Mb byte array, microseconds: 829967 Serial 210Mb byte array, microseconds: 298365 Parallel 210Mb byte array, microseconds: 823702 Serial 218Mb byte array, microseconds: 311791 Parallel 218Mb byte array, microseconds: 753300 Serial 226Mb byte array, microseconds: 327196 Parallel 226Mb byte array, microseconds: 786166 Serial 234Mb byte array, microseconds: 333410 Parallel 234Mb byte array, microseconds: 809886 Serial 242Mb byte array, microseconds: 352284 Parallel 242Mb byte array, microseconds: 845802 Serial 250Mb byte array, microseconds: 358615 Parallel 250Mb byte array, microseconds: 897478 Serial 258Mb byte array, microseconds: 373060 Parallel 258Mb byte array, microseconds: 894993
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д