예제 #1
0
        public void TestReentrancyInEnumeration()
        {
            var lst = new LifetimedList <Action>();
            var l1  = new LifetimeDefinition {
                Id = "l1"
            };
            var l2 = new LifetimeDefinition {
                Id = "l2"
            };

            l2.Lifetime.OnTermination(() => lst.ClearValuesIfNotAlive());

            var log = new List <int>();

            lst.Add(l1.Lifetime, () =>
            {
                log.Add(1);
                lst.Add(l1.Lifetime, () =>
                {
                    log.Add(2);
                });
                l2.Terminate();
            });

            lst.Add(l2.Lifetime, () => { log.Add(3); });

            void Enumerate()
            {
                foreach (var(lf, action) in lst)
                {
                    if (lf.IsNotAlive)
                    {
                        continue;
                    }
                    action.Invoke();
                }
            }

            Enumerate();
            Assert.AreEqual(new List <int> {
                1
            }, log);
            log.Clear();

            Enumerate();
            Assert.AreEqual(new List <int> {
                1, 2
            }, log);
            log.Clear();


            Enumerate();
            Assert.AreEqual(new List <int> {
                1, 2, 2
            }, log);
        }
예제 #2
0
        public void TestSimple()
        {
            var lst = new LifetimedList <int>();

            var l1 = new LifetimeDefinition();

            l1.Lifetime.OnTermination(() => lst.ClearValuesIfNotAlive());
            lst.Add(l1.Lifetime, 1);
            lst.Add(l1.Lifetime, 2);

            var l2 = new LifetimeDefinition();

            l2.Lifetime.OnTermination(() => lst.ClearValuesIfNotAlive());
            lst.AddPriorityItem(new ValueLifetimed <int>(l2.Lifetime, 3));
            lst.AddPriorityItem(new ValueLifetimed <int>(l2.Lifetime, 4));

            Assert.AreEqual(new List <int> {
                3, 4, 1, 2
            }, lst.Select(x => x.Value).ToList());

            l1.Terminate();
            Assert.AreEqual(new List <int> {
                3, 4
            }, lst.Select(x => x.Value).ToList());

            lst.Add(l2.Lifetime, 5);
            Assert.AreEqual(new List <int> {
                3, 4, 5
            }, lst.Select(x => x.Value).ToList());

            l2.Terminate();
            Assert.AreEqual(new List <int> {
            }, lst.Select(x => x.Value).ToList());

            //again
            l1 = new LifetimeDefinition();
            l2 = new LifetimeDefinition();

            lst.Add(l1.Lifetime, 1);
            Assert.AreEqual(new List <int> {
                1
            }, lst.Select(x => x.Value).ToList());

            lst.AddPriorityItem(new ValueLifetimed <int>(l2.Lifetime, 2));
            Assert.AreEqual(new List <int> {
                2, 1
            }, lst.Select(x => x.Value).ToList());
        }
예제 #3
0
        public void PriorityItemTest()
        {
            using var lifetimeDefinition = new LifetimeDefinition();
            var lifetime = lifetimeDefinition.Lifetime;

            var list = new LifetimedList <int>();

            list.Add(lifetime, 1);
            list.Add(lifetime, 2);

            using (var enumerator = list.GetEnumerator())
            {
                Assert.IsTrue(enumerator.MoveNext());
                Assert.AreEqual(1, enumerator.Current.Value);

                list.AddPriorityItem(lifetime, 3);

                Assert.IsTrue(enumerator.MoveNext());
                Assert.AreEqual(2, enumerator.Current.Value);

                Assert.IsFalse(enumerator.MoveNext());
            }

            using (var enumerator = list.GetEnumerator())
            {
                Assert.IsTrue(enumerator.MoveNext());
                Assert.AreEqual(3, enumerator.Current.Value);

                list.AddPriorityItem(lifetime, 4);

                Assert.IsTrue(enumerator.MoveNext());
                Assert.AreEqual(1, enumerator.Current.Value);

                Assert.IsTrue(enumerator.MoveNext());
                Assert.AreEqual(2, enumerator.Current.Value);

                Assert.IsFalse(enumerator.MoveNext());
            }
        }
예제 #4
0
        public virtual void Advise(Lifetime lifetime, Action <T> handler)
        {
            if (!lifetime.IsAlive)
            {
                return;
            }

            if (Signal.IsPriorityAdvise)
            {
                myListeners.AddPriorityItem(lifetime, handler);
            }
            else
            {
                myListeners.Add(lifetime, handler);
            }

            lifetime.TryOnTermination(this);
        }
예제 #5
0
        public void EnumerationStressTest()
        {
            var hugeStruct = HugeStruct.Create();

            for (var k = 0; k < 300; k++)
            {
                using var lifetimeDefinition = new LifetimeDefinition();
                var lifetime = lifetimeDefinition.Lifetime;

                var list = new LifetimedList <HugeStruct>();
                // ReSharper disable once MethodSupportsCancellation
                var task = Task.Factory.StartNew(() =>
                {
                    for (var j = 0; j < 3; j++)
                    {
                        Task.Factory.StartNew(() =>
                        {
                            // ReSharper disable once AccessToDisposedClosure
                            using (lifetimeDefinition)
                            {
                                while (lifetime.IsAlive)
                                {
                                    list.ClearValuesIfNotAlive();
                                }
                            }
                        }, TaskCreationOptions.AttachedToParent | TaskCreationOptions.LongRunning);

                        Task.Factory.StartNew(() =>
                        {
                            // ReSharper disable once AccessToDisposedClosure
                            using (lifetimeDefinition)
                            {
                                while (lifetime.IsAlive)
                                {
                                    var copy = new List <ValueLifetimed <HugeStruct> >(); // fast enumeration
                                    foreach (var lifetimed in list)
                                    {
                                        copy.Add(lifetimed);
                                    }

                                    foreach (var value in copy)
                                    {
                                        value.Value.AssertValues();
                                        if (lifetime.IsNotAlive)
                                        {
                                            return;
                                        }
                                    }
                                }
                            }
                        }, TaskCreationOptions.AttachedToParent | TaskCreationOptions.LongRunning);

                        Task.Factory.StartNew(() =>
                        {
                            // ReSharper disable once AccessToDisposedClosure
                            using (lifetimeDefinition)
                            {
                                while (lifetime.IsAlive)
                                {
                                    foreach (var value in list) // slow enumeration
                                    {
                                        value.Value.AssertValues();
                                        if (lifetime.IsNotAlive)
                                        {
                                            return;
                                        }

                                        Thread.Sleep(1);
                                    }
                                }
                            }
                        }, TaskCreationOptions.AttachedToParent | TaskCreationOptions.LongRunning);
                    }
                });

                Parallel.Invoke(() =>
                {
                    using (lifetimeDefinition)
                    {
                        for (var i = 0; i < 100; i++)
                        {
                            using var localDef = lifetime.CreateNested();
                            for (var j = 0; j < i; j++)
                            {
                                list.Add(localDef.Lifetime, hugeStruct);
                            }

                            if (lifetime.IsNotAlive)
                            {
                                break;
                            }
                        }
                    }
                }, () =>
                {
                    var spinWait = new SpinWait();
                    for (var i = 0; i < 100; i++)
                    {
                        list.AddPriorityItem(lifetime, hugeStruct);
                        if (lifetime.IsNotAlive)
                        {
                            break;
                        }
                        spinWait.SpinOnce();
                    }
                });

                task.Wait();
            }
        }