Многопоточный геттер System.IndexOutOfRangeException - C#

Узнай цену своей работы

Формулировка задачи:

Есть такой код, так вот не могу понять почему в переменную next, которая используется как счетчик проскакивает число больше массива байтов, когда по идее запрос значения next должен пройти через геттер функцию и там в данном случае попасть в цикл, пока значение next не станет меньше размера массива байтов, но периодически 2 - 3 параллельно работающих потока с первым потоком (поток, который запускает поток Seed(0) и переходит в ожидание завершения запущенного потока) не останавливаясь в геттере забирают значение переменной next больше размера массива.
Листинг программы
  1. public static class Random
  2. {
  3. // 4 Mb Random bytes buffer
  4. private static byte[] seedArr = new byte[4194304];
  5. private static Thread waiter;
  6. private static long _next;
  7. private static long next
  8. {
  9. get
  10. {
  11. if (_next >= seedArr.LongLength && waiter == null)
  12. {
  13. waiter = new Thread(() => Seed(0));
  14. waiter.Start();
  15. waiter.Join();
  16. waiter = null;
  17. _next = 0;
  18. }
  19. while (_next >= seedArr.LongLength)
  20. {
  21. if (waiter != null && waiter.ThreadState == ThreadState.Running)
  22. {
  23. waiter.Join();
  24. }
  25. Thread.SpinWait(1);
  26. }
  27. return _next;
  28. }
  29. set
  30. {
  31. _next = value;
  32. }
  33. }
  34. public static void Seed(ulong Seed)
  35. {
  36. if (Seed.GetType() != typeof(ulong) || Seed <= 0)
  37. {
  38. RNGCryptoServiceProvider CSP = new RNGCryptoServiceProvider();
  39. byte[] bytes = new byte[8];
  40. CSP.GetNonZeroBytes(bytes);
  41. CSP.Dispose();
  42. Seed = BitConverter.ToUInt64(bytes, 0);
  43. }
  44. {
  45. ulong[] ticks = new ulong[4] {
  46. ulong.MaxValue,
  47. Convert.ToUInt64(DateTime.UtcNow.Ticks),
  48. Convert.ToUInt64(Environment.TickCount),
  49. Convert.ToUInt64(Thread.CurrentThread.ManagedThreadId)
  50. };
  51. ulong[] modules_a = new ulong[4] {
  52. ticks[0] / ticks[1],
  53. ticks[0] % ticks[1],
  54. ticks[0] / ticks[2],
  55. ticks[0] % ticks[2]
  56. };
  57. byte[] bytes = new byte[8];
  58. {
  59. byte[] bytes_t = new byte[524288];
  60. {
  61. byte[] sbytes = BitConverter.GetBytes(Seed);
  62. MemoryStream bytebuff = new MemoryStream();
  63. bytebuff.Write(sbytes, 0, sbytes.Length);
  64. Extensions.ParallelFor(1, 4, i =>
  65. {
  66. byte[] tbytes = BitConverter.GetBytes(ticks[i]);
  67. lock (bytebuff)
  68. {
  69. bytebuff.Write(tbytes, 0, tbytes.Length);
  70. }
  71. });
  72. Extensions.ParallelFor(0, 4, i =>
  73. {
  74. byte[] mbytes = BitConverter.GetBytes(modules_a[i]);
  75. lock (bytebuff)
  76. {
  77. bytebuff.Write(mbytes, 0 , mbytes.Length);
  78. }
  79. });
  80. byte[] seedb = bytebuff.ToArray();
  81. bytebuff.Dispose();
  82. {
  83. byte[] rseedb = seedb;
  84. rseedb.Reverse();
  85. int sl = seedb.Length, rsl = rseedb.Length;
  86. MemoryStream buff = new MemoryStream();
  87. buff.Write(seedb, 0, sl);
  88. buff.Write(rseedb, 0, rsl);
  89. for (int i = 0; i < 2; i++)
  90. {
  91. rseedb = buff.ToArray();
  92. buff.Write(rseedb, 0, rseedb.Length);
  93. }
  94. seedb = buff.ToArray();
  95. buff.Dispose();
  96. }
  97. RNGCryptoServiceProvider CSP = new RNGCryptoServiceProvider();
  98. HMACMD5 hmacmd5 = new HMACMD5(seedb);
  99. HMACSHA512 hmacsha512 = new HMACSHA512(seedb);
  100. CSP.GetNonZeroBytes(bytes_t);
  101. byte[] md5 = hmacmd5.ComputeHash(bytes_t, 0, bytes_t.Length), sha512 = hmacsha512.ComputeHash(bytes_t, 0, bytes_t.Length);
  102. CSP.Dispose();
  103. hmacmd5.Dispose();
  104. hmacsha512.Dispose();
  105. long md5l = md5.LongLength, sha512l = sha512.LongLength;
  106. // for (int i = 0, l = bytes_t.Length, pos = 0; i < l; i++)
  107. Extensions.ParallelFor(0, bytes_t.LongLength, i =>
  108. {
  109. long posmd5 = i % md5l, possha512 = i % sha512l;
  110. bytes_t[i] ^= md5[posmd5];
  111. bytes_t[i] ^= sha512[possha512];
  112. });
  113. md5 = null;
  114. sha512 = null;
  115. }
  116. Extensions.ParallelFor(0, bytes_t.LongLength, i =>
  117. {
  118. long pos = i % 8;
  119. lock (bytes)
  120. {
  121. bytes[pos] ^= bytes_t[i];
  122. }
  123. });
  124. bytes_t = null;
  125. }
  126. ulong modules = Convert.ToUInt64(Seed) ^ BitConverter.ToUInt64(bytes, 0), modules_x = 0, modules_t = 0, modules_xt = 0;
  127. modules_x = modules_a[0] ^ modules_a[1] ^ modules_a[2] ^ modules_a[3];
  128. modules_t = modules_x >> 1;
  129. modules_t = modules_x % modules_t;
  130. modules_t = modules_x ^ modules_t;
  131. ticks[1] ^= ticks[3];
  132. modules_xt = ticks[1] % modules_t;
  133. modules = modules ^ modules_t ^ modules_xt;
  134. Seed = modules;
  135. }
  136. {
  137. RNGCryptoServiceProvider CSP = new RNGCryptoServiceProvider();
  138. CSP.GetNonZeroBytes(seedArr);
  139. CSP.Dispose();
  140. byte[] bytes = BitConverter.GetBytes(Seed);
  141. Extensions.ParallelFor(0, seedArr.LongLength, i =>
  142. {
  143. long pos = i % 8;
  144. lock (seedArr)
  145. {
  146. seedArr[i] ^= bytes[pos];
  147. }
  148. });
  149. }
  150. Seed = 0;
  151. }
  152. private static byte GetByte()
  153. {
  154. byte retbyte;
  155. retbyte = seedArr[next]; // Здесь System.IndexOutOfRangeException
  156. next++;
  157. return retbyte;
  158. }
  159. public static byte[] NextBytes(ulong count = 1)
  160. {
  161. byte[] bytes = new byte[count];
  162. // for (int i = 0; i < count; i++)
  163. Extensions.ParallelFor(0, bytes.LongLength, i =>
  164. {
  165. byte lbyte = GetByte();
  166. bytes[i] = lbyte;
  167. });
  168. return bytes;
  169. }
  170. }

Решение задачи: «Многопоточный геттер System.IndexOutOfRangeException»

textual
Листинг программы
  1. Timer frequency as ticks per microsecond: 2343835000000
  2. Timer is high-resolution: True
  3. Max parallel threads pass: 4
  4. Serial 1Mb byte array, microseconds: 1375
  5. Parallel 1Mb byte array, microseconds: 3253
  6. Serial 2Mb byte array, microseconds: 2799
  7. Parallel 2Mb byte array, microseconds: 7084
  8. Serial 10Mb byte array, microseconds: 14196
  9. Parallel 10Mb byte array, microseconds: 33382
  10. Serial 18Mb byte array, microseconds: 25609
  11. Parallel 18Mb byte array, microseconds: 61043
  12. Serial 26Mb byte array, microseconds: 36987
  13. Parallel 26Mb byte array, microseconds: 85168
  14. Serial 34Mb byte array, microseconds: 48284
  15. Parallel 34Mb byte array, microseconds: 113083
  16. Serial 42Mb byte array, microseconds: 59928
  17. Parallel 42Mb byte array, microseconds: 140026
  18. Serial 50Mb byte array, microseconds: 71676
  19. Parallel 50Mb byte array, microseconds: 166940
  20. Serial 58Mb byte array, microseconds: 84363
  21. Parallel 58Mb byte array, microseconds: 194119
  22. Serial 66Mb byte array, microseconds: 94159
  23. Parallel 66Mb byte array, microseconds: 220923
  24. Serial 74Mb byte array, microseconds: 105542
  25. Parallel 74Mb byte array, microseconds: 244599
  26. Serial 82Mb byte array, microseconds: 116878
  27. Parallel 82Mb byte array, microseconds: 277487
  28. Serial 90Mb byte array, microseconds: 128088
  29. Parallel 90Mb byte array, microseconds: 297518
  30. Serial 98Mb byte array, microseconds: 139974
  31. Parallel 98Mb byte array, microseconds: 330158
  32. Serial 106Mb byte array, microseconds: 151253
  33. Parallel 106Mb byte array, microseconds: 356841
  34. Serial 114Mb byte array, microseconds: 161735
  35. Parallel 114Mb byte array, microseconds: 396256
  36. Serial 122Mb byte array, microseconds: 173373
  37. Parallel 122Mb byte array, microseconds: 413497
  38. Serial 130Mb byte array, microseconds: 185386
  39. Parallel 130Mb byte array, microseconds: 439991
  40. Serial 138Mb byte array, microseconds: 197546
  41. Parallel 138Mb byte array, microseconds: 464581
  42. Serial 146Mb byte array, microseconds: 209185
  43. Parallel 146Mb byte array, microseconds: 501030
  44. Serial 154Mb byte array, microseconds: 220108
  45. Parallel 154Mb byte array, microseconds: 535607
  46. Serial 162Mb byte array, microseconds: 232093
  47. Parallel 162Mb byte array, microseconds: 559694
  48. Serial 170Mb byte array, microseconds: 242831
  49. Parallel 170Mb byte array, microseconds: 592954
  50. Serial 178Mb byte array, microseconds: 255106
  51. Parallel 178Mb byte array, microseconds: 630598
  52. Serial 186Mb byte array, microseconds: 272178
  53. Parallel 186Mb byte array, microseconds: 797705
  54. Serial 194Mb byte array, microseconds: 275468
  55. Parallel 194Mb byte array, microseconds: 782837
  56. Serial 202Mb byte array, microseconds: 286021
  57. Parallel 202Mb byte array, microseconds: 829967
  58. Serial 210Mb byte array, microseconds: 298365
  59. Parallel 210Mb byte array, microseconds: 823702
  60. Serial 218Mb byte array, microseconds: 311791
  61. Parallel 218Mb byte array, microseconds: 753300
  62. Serial 226Mb byte array, microseconds: 327196
  63. Parallel 226Mb byte array, microseconds: 786166
  64. Serial 234Mb byte array, microseconds: 333410
  65. Parallel 234Mb byte array, microseconds: 809886
  66. Serial 242Mb byte array, microseconds: 352284
  67. Parallel 242Mb byte array, microseconds: 845802
  68. Serial 250Mb byte array, microseconds: 358615
  69. Parallel 250Mb byte array, microseconds: 897478
  70. Serial 258Mb byte array, microseconds: 373060
  71. Parallel 258Mb byte array, microseconds: 894993

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

5   голосов , оценка 4 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут