Beispiel #1
0
            public CursorBranch(Cursor <T> cursor, int currentIndex, CompositeDisposable parentDisposables)
            {
                Contract.Requires(cursor != null);
                Contract.Requires(cursor.branches != null);
                Contract.Requires(cursor.elements != null);
                Contract.Requires(cursor.latestIndex >= -1);
                Contract.Requires(currentIndex >= 0);
                Contract.Requires(currentIndex >= cursor.firstElementIndex);
                Contract.Requires(currentIndex > cursor.latestIndex || cursor.elements.Count >= cursor.latestIndex - currentIndex);
                Contract.Requires(!cursor.stopped || currentIndex <= cursor.latestIndex + 1);
                Contract.Requires(parentDisposables != null);
                Contract.Ensures(this.cursor == cursor);
                Contract.Ensures(this.currentIndex == currentIndex);
                Contract.Ensures(IsForwardOnly == cursor.IsForwardOnly);
                Contract.Ensures(IsSequenceTerminated == cursor.IsSequenceTerminated);
                Contract.Ensures(LatestIndex == cursor.latestIndex);
                Contract.Ensures(CurrentIndex == currentIndex);
                Contract.Ensures(AtEndOfSequence == (cursor.IsSequenceTerminated && currentIndex == cursor.latestIndex + 1));
                Contract.Ensures(cursor.AtEndOfSequence == Contract.OldValue(cursor.AtEndOfSequence));

                this.cursor       = cursor;
                this.currentIndex = currentIndex;

                parentDisposables.Add(this);
                cursor.branches.Add(this);

                bool removed = false;

                var subscription = Disposable.Create(() =>
                {
                    if (!removed)
                    {
                        // Set this variable first in case of reentry.
                        removed = true;

                        parentDisposables.Remove(this);
                        cursor.branches.Remove(this);
                    }
                });

                disposables.Add(subscription);

                Contract.Assert(currentIndex > cursor.latestIndex || cursor.elements.Count >= cursor.latestIndex - currentIndex);
            }
Beispiel #2
0
    protected override void Main()
    {
      TraceDescription(Instructions.MulticastLab);

      int current = 0;

      IObservable<int> source = Observable
        .Interval(TimeSpan.FromSeconds(1))
        .Select(_ => current++)
        .Multicast(() => new ReplaySubject<int>())
        .RefCount();

      using (var disposables = new CompositeDisposable())
      {
        do
        {
          var key = WaitForKey();

          switch (key.KeyChar)
          {
            case '+':
            case '=':
              var id = (char)('A' + disposables.Count);

              var subscription = source.Subscribe(ConsoleOutput(id.ToString()));

              disposables.Add(subscription);
              break;
            case '-':
            case '_':
              if (disposables.Count > 0)
              {
                disposables.Remove(disposables.Last());
              }
              break;
            default:
              return;
          }
        }
        while (true);
      }
    }
Beispiel #3
0
        public static IDisposable Schedule(this IScheduler scheduler, Action<Action> action)
        {
            // InvokeRec1
            var group = new CompositeDisposable(1);
            var gate = new object();

            Action recursiveAction = null;
            recursiveAction = () => action(() =>
            {
                var isAdded = false;
                var isDone = false;
                var d = default(IDisposable);
                d = scheduler.Schedule(() =>
                {
                    lock (gate)
                    {
                        if (isAdded)
                            group.Remove(d);
                        else
                            isDone = true;
                    }
                    recursiveAction();
                });

                lock (gate)
                {
                    if (!isDone)
                    {
                        group.Add(d);
                        isAdded = true;
                    }
                }
            });

            group.Add(scheduler.Schedule(recursiveAction));

            return group;
        }
Beispiel #4
0
        public void CompositeDisposable_RemoveOptimizationBehavior()
        {
            var g = new CompositeDisposable();
            var m = new Dictionary<int, IDisposable>();
            var r = new List<int>();

            var N = 100;

            for (int i = 0; i < N; i++)
            {
                var j = i;

                var d = Disposable.Create(() => r.Add(j));
                m[j] = d;
                g.Add(d);
            }

            var d1 = Enumerable.Range(0, N).Where(i => i % 2 == 0).ToArray();
            foreach (var i in d1)
                g.Remove(m[i]);
            Assert.IsTrue(r.SequenceEqual(d1));

            var d2 = Enumerable.Range(0, N).Where(i => i % 3 == 0).ToArray();
            foreach (var i in d2)
                g.Remove(m[i]);
            Assert.IsTrue(r.SequenceEqual(d1.Concat(d2.Where(x => !d1.Any(y => x == y)))));

            var d3 = Enumerable.Range(0, N).Where(i => i % 5 == 0).ToArray();
            foreach (var i in d3)
                g.Remove(m[i]);
            Assert.IsTrue(r.SequenceEqual(d1.Concat(d2.Where(x => !d1.Any(y => x == y))).Concat(d3.Where(x => !d1.Any(y => x == y) && !d2.Any(y => x == y)))));

            g.Dispose();

            var z = r.Except(d1.Union(d2).Union(d3)).ToArray();
            Assert.IsTrue(z.SequenceEqual(Enumerable.Range(0, N).Where(i => !(i % 2 == 0 || i % 3 == 0 || i % 5 == 0))));
        }
Beispiel #5
0
        public void CompositeDisposable_Remove()
        {
            var disp1 = false;
            var disp2 = false;

            var d1 = Disposable.Create(() => { disp1 = true; });
            var d2 = Disposable.Create(() => { disp2 = true; });
            var g = new CompositeDisposable(d1, d2);

            Assert.AreEqual(2, g.Count);
            Assert.IsTrue(g.Contains(d1));
            Assert.IsTrue(g.Contains(d2));

            Assert.IsTrue(g.Remove(d1));
            Assert.AreEqual(1, g.Count);
            Assert.IsFalse(g.Contains(d1));
            Assert.IsTrue(g.Contains(d2));
            Assert.IsTrue(disp1);

            Assert.IsTrue(g.Remove(d2));
            Assert.IsFalse(g.Contains(d1));
            Assert.IsFalse(g.Contains(d2));
            Assert.IsTrue(disp2);

            var disp3 = false;
            var d3 = Disposable.Create(() => { disp3 = true; });
            Assert.IsFalse(g.Remove(d3));
            Assert.IsFalse(disp3);
        }
Beispiel #6
0
        static void Impl(int disposeAt)
        {
            var rand = new Random();

            var g = new CompositeDisposable();

            Console.Write("Dispose @ = {0} - ", disposeAt);

            if (disposeAt == 0)
            {
                g.Dispose();
                Console.Write("{GD} ");
            }

            if (disposeAt == 1)
            {
                var sleep = rand.Next(0, 5) > 1 /* 60% chance */ ? rand.Next(2, 1000) : 0;

                ThreadPool.QueueUserWorkItem(_ =>
                {
                    Helpers.SleepOrSpin(sleep);
                    g.Dispose();
                    Console.Write("{GD} ");
                });
            }

            var n = rand.Next(0, 1000);
            var cd = new CountdownEvent(n);

            var ds = Enumerable.Range(0, n).Select(_ => Disposable.Create(() => cd.Signal())).ToArray();

            var m = rand.Next(1, 100);
            var jobs = ds.GroupBy(_ => rand.Next() % m).Select(Enumerable.ToList).ToList();

            Console.Write("N = {0}, M = {1} - ", n, m);

            var done = new CountdownEvent(jobs.Count);

            foreach (var job in jobs)
            {
                var sleep = rand.Next(0, 10) == 0 /* 10% chance */ ? rand.Next(2, 100) : 0;
                var sleepAt = Enumerable.Range(0, rand.Next(0, job.Count) / rand.Next(1, 100)).ToArray();
                var sleeps = sleepAt.Select(_ => rand.Next(0, 50)).ToArray();

                var rem = rand.Next(0, 3) == 0; /* 33% chance */
                var remAt = rand.Next(0, 10) == 0 /* 10% chance */ ? rand.Next(2, 100) : 0;

                var mine = job;
                ThreadPool.QueueUserWorkItem(_ =>
                {
                    Helpers.SleepOrSpin(sleep);

                    var j = 0;
                    foreach (var d in mine)
                    {
                        var dd = d;

                        if (sleepAt.Contains(j))
                            Helpers.SleepOrSpin(sleeps[j]);

                        g.Add(dd);
                        Console.Write("+");

                        if (rem)
                        {
                            ThreadPool.QueueUserWorkItem(__ =>
                            {
                                Helpers.SleepOrSpin(remAt);
                                g.Remove(dd);
                                Console.Write("-");
                            });
                        }

                        j++;
                    }

                    done.Signal();
                });
            }

            done.Wait();

            if (disposeAt == 2)
            {
                g.Dispose();
                Console.Write("{GD} ");
            }

            cd.Wait();

            Console.WriteLine(".");
        }