Многопоточный геттер 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

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


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

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

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