public void MultipleDeserializeCallsShouldNotContend()
        {
            var data = new ThreadRace.Y9();

            byte[] raw;
            using (var ms = new MemoryStream())
            {
                RuntimeTypeModel.Create().Serialize(ms, data);
                raw = ms.ToArray();
                Assert.True(raw.Length > 0);
            }

            const int threads = 10, loop = 500;

            for (int loopIndex = 0; loopIndex < loop; loopIndex++)
            {
                int              building = threads, error = 0;
                Thread[]         threadArr = new Thread[threads];
                ManualResetEvent evt       = new ManualResetEvent(false);
                var              model     = RuntimeTypeModel.Create();
                string           eek       = null;
                int              eekCount  = 0;
                model.LockContended += (s, a) => { eek = a.OwnerStackTrace;
                                                   Interlocked.Increment(ref eekCount); };
                for (int i = 0; i < threads; i++)
                {
                    threadArr[i] = new Thread(() =>
                    {
                        try
                        {
                            using var ms = new MemoryStream(raw);
                            if (Interlocked.Decrement(ref building) == 0)
                            {
                                evt.Set();
                            }
                            else
                            {
                                evt.WaitOne();
                            }
#pragma warning disable CS0618
                            ThreadRace.A a =
                                (ThreadRace.A)model.Deserialize(ms, null, typeof(ThreadRace.A));
#pragma warning restore CS0618
                            Assert.IsType <ThreadRace.Y9>(a);
                        }
                        catch
                        {
                            Interlocked.Increment(ref error);
                        }
                    });
                }
                foreach (var thd in threadArr)
                {
                    thd.Start();
                }
                foreach (var thd in threadArr)
                {
                    if (!thd.Join(4000))
                    {
                        throw new TimeoutException();
                    }
                }
                Assert.Equal(0, Interlocked.CompareExchange(ref error, 0, 0));
                Assert.Null(eek);
                Assert.Equal(0, Interlocked.CompareExchange(ref eekCount, 0, 0));
            }
        }
示例#2
0
        public void MultipleDeserializeCallsShouldNotContend()
        {
            var data = new ThreadRace.Y9();

            byte[] raw;
            using (var ms = new MemoryStream())
            {
                RuntimeTypeModel.Create().Serialize(ms, data);
                raw = ms.ToArray();
                Assert.That(raw.Length, Is.GreaterThan(0));
            }

#if DEBUG
            const int threads = 5;
            const int loop    = 5;
#else
            const int threads = 10;
            const int loop    = 500;
#endif

            for (int loopIndex = 0; loopIndex < loop; loopIndex++)
            {
                int              building = threads, error = 0;
                Thread[]         threadArr = new Thread[threads];
                ManualResetEvent evt       = new ManualResetEvent(false);
                var              model     = RuntimeTypeModel.Create();
                model.SkipCompiledVsNotCheck = true;
                string eek      = null;
                int    eekCount = 0;
                model.LockContended += (s, a) => { eek = a.OwnerStackTrace;
                                                   Interlocked.Increment(ref eekCount); };
                for (int i = 0; i < threads; i++)
                {
                    threadArr[i] = new Thread(() =>
                    {
                        try
                        {
                            using (var ms = new MemoryStream(raw))
                            {
                                if (Interlocked.Decrement(ref building) == 0)
                                {
                                    evt.Set();
                                }
                                else
                                {
                                    evt.WaitOne();
                                }
                                ThreadRace.A a =
                                    (ThreadRace.A)model.Deserialize(ms, null, typeof(ThreadRace.A));
                                Assert.That(a, Is.InstanceOfType(typeof(ThreadRace.Y9)));
                            }
                        }
                        catch
                        {
                            Interlocked.Increment(ref error);
                        }
                    });
                }
                foreach (var thd in threadArr)
                {
                    thd.Start();
                }
                foreach (var thd in threadArr)
                {
                    if (!thd.Join(4000))
                    {
                        throw new TimeoutException();
                    }
                }
                Assert.That(Interlocked.CompareExchange(ref error, 0, 0), Is.EqualTo(0));
                Assert.That(eek, Is.Null);
                Assert.That(Interlocked.CompareExchange(ref eekCount, 0, 0), Is.EqualTo(0));
            }
        }