public void SelectDisposableShouldWork()
        {
            var scheduler = new TestScheduler();
            var disposables = new List<BooleanDisposable>();
            var list = new CompositeDisposable();
            scheduler.CreateColdObservable(
                new Recorded<Notification<long>>(100, Notification.CreateOnNext(0L)),
                new Recorded<Notification<long>>(200, Notification.CreateOnNext(1L)),
                new Recorded<Notification<long>>(300, Notification.CreateOnNext(2L)),
                new Recorded<Notification<long>>(400, Notification.CreateOnNext(3L)),
                new Recorded<Notification<long>>(400, Notification.CreateOnCompleted<long>())
            )
            .SelectDisposable(list, i => {
                var d = new BooleanDisposable();
                disposables.Add(d);
                return d;
            }, (i, _) => i)
            .Subscribe()
            .DisposeWith(list);

            scheduler.AdvanceTo(300);

            disposables.Count.Should().Be(3);

            disposables.Select(d => d.IsDisposed).Should().NotContain(true);

            list.Dispose();

            disposables.Select(d => d.IsDisposed).Should().NotContain(false);

        }
    public static void Run()
    {
      var systems = new[] { "A", "B", "C" }.Select(CreateExternalSystem);
      var observables = systems.Select(s => s.ObserveHealth()).Select(obs => obs.DistinctUntilChanged(c => c.IsAvailable)).ToList();
      var disposable = new CompositeDisposable();

      // observe independently
      disposable.Add(new CompositeDisposable(observables.Select(c => c.Subscribe(PrintHealthCheck))));

      // merge
      var merged = observables.Aggregate((l, r) => l.Merge(r));
      disposable.Add(merged.Subscribe(PrintHealthCheck));

      // combine
      var combined = observables
        .Aggregate(Observable.Return(Enumerable.Empty<HealthCheck>()), (agg, obs) => agg.CombineLatest(obs, (checks, check) => checks.Concat(new[] { check })));

      var scan = merged.Scan(ImmutableDictionary<string, bool>.Empty, (d, check) => d.SetItem(check.ExternalSystemName, check.IsAvailable));
      
      disposable.Add(combined.Subscribe(e => Console.WriteLine("Combined: " + string.Join(", ", e.Select(c => $"{c.ExternalSystemName}={c.IsAvailable}")))));
      disposable.Add(scan.Subscribe(d => Console.WriteLine("Scanned: " + string.Join(", ", d.Select(p => $"{p.Key}={p.Value}")))));

      Console.ReadKey();
      disposable.Dispose();
    }
 public async Task<IObservable<ArmaServerInfo>> GetServers(CancellationToken ct, ServerFilterWrap filter) {
     var dsp = new CompositeDisposable();
     // Apparently we get null ServerInfo (not even endpoints :S)
     var obs = ServerResponses
         .TakeUntil(RefreshComplete)
         .Select(x => x.ServerInfo == null ? null : ArmaServerInfo.FromWrap(x.ServerIndex, x.ServerInfo))
         .Where(x => x != null)
         .Replay();
     dsp.Add(obs.Connect());
     obs.Subscribe(_ => { }, x => dsp.Dispose(), dsp.Dispose, ct);
     ct.Register(dsp.Dispose);
     await GetServerInfo(filter).ConfigureAwait(false);
     return obs;
 }
Beispiel #4
0
        static InputModel()
        {
            _disposables = new CompositeDisposable();
            _core = new InputCoreModel();
            _accounts = new AccountSelectorModel(_core);

            // link property changing
            var icmpc = new PropertyChangedEventListener(_core);
            icmpc.RegisterHandler(() => _core.CurrentInputData,
                                (o, e) => _accounts.CurrentInputDataChanged());
            _disposables.Add(icmpc);
            SetEventPropagation();

            App.ApplicationFinalize += () => _disposables.Dispose();
        }
 private IConnectableObservable<ArmaServerInfo> PrepareListener(CancellationToken ct, bool inclRules = false) {
     var dsp = new CompositeDisposable();
     var obs = BuildListener(dsp);
     if (inclRules)
         obs = obs
             .SelectMany(async si => {
                 await UpdateRules(si, ct).ConfigureAwait(false);
                 return si;
             });
     var theObs = obs.Select(x => x.Info)
         .Replay();
     dsp.Add(theObs.Connect());
     theObs.Subscribe(_ => { }, x => dsp.Dispose(), dsp.Dispose, ct);
     ct.Register(dsp.Dispose);
     return theObs;
 }
 public void Order()
 {
     // It is time-dependent test (i.e. lengthy and inconsistent), which is not very good but we cannot use HistoricalScheduler to test it...
     var s = Scheduler.ThreadPool;
     var l = new List<int> ();
     var dis = new CompositeDisposable ();
     try {
         dis.Add (s.Schedule (() => { Thread.Sleep (1200); l.Add (1); }));
         dis.Add (s.Schedule (() => { Thread.Sleep (800); l.Add (2); }));
         dis.Add (s.Schedule (() => { Thread.Sleep (50); l.Add (3); }));
         Thread.Sleep (1500);
         Assert.AreEqual (new int [] {3, 2, 1}, l.ToArray (), "#1");
     } finally {
         dis.Dispose ();
     }
 }
Beispiel #7
0
        private static void CompositeDisposable()
        {
            Demo.DisplayHeader("The CompositeDisposable - groups multiple disposables and dispose them together");

            var compositeDisposable = new CompositeDisposable(
                Disposable.Create(() => Console.WriteLine("1st disposed")),
                Disposable.Create(() => Console.WriteLine("2nd disposed")));

            compositeDisposable.Dispose();

            //The same can also be written using the Add() method
            compositeDisposable = new CompositeDisposable();
            compositeDisposable.Add(Disposable.Create(() => Console.WriteLine("1st disposed")));
            compositeDisposable.Add(Disposable.Create(() => Console.WriteLine("2nd disposed")));

            compositeDisposable.Dispose();
        }
 public void Order()
 {
     // It is time-dependent test (i.e. lengthy and inconsistent), which is not very good but we cannot use HistoricalScheduler to test it...
     var s = Scheduler.TaskPool;
     var l = new List<int> ();
     var dis = new CompositeDisposable ();
     try {
         // If the tasks do not run long enough, the (Task) scheduler will not use separate Threads,
         // therefore Thread.Sleep(x) will block not only current task, but also tasks scheduled to run
         // in the same Thread
         dis.Add (s.Schedule (() => { Thread.Sleep (2400); l.Add (1); }));
         dis.Add (s.Schedule (() => { Thread.Sleep (1600); l.Add (2); }));
         dis.Add (s.Schedule (() => { Thread.Sleep (50); l.Add (3); }));
         Thread.Sleep (2500);
         Assert.AreEqual (new int [] {3, 2, 1}, l.ToArray (), "#1");
     } finally {
         dis.Dispose ();
     }
 }
    public static void Run()
    {
      var systems = new[] { "A", "B", "C" }.Select(CreateExternalSystem);
      var observables = systems.Select(s => s.ObserveHealth()).Select(obs => obs.DistinctUntilChanged(c => c.IsAvailable)).ToList();
      var disposable = new CompositeDisposable();

      // observe independently
      disposable.Add(new CompositeDisposable(observables.Select(c => c.Subscribe(PrintHealthCheck))));

      // merge
      var merged = Observable.Empty<HealthCheck>();
      disposable.Add(merged.Subscribe(PrintHealthCheck));

      // combine
      var combined = Observable.Empty<IEnumerable<HealthCheck>>();

      disposable.Add(combined.Subscribe(e => Console.WriteLine("Combined: " + string.Join(", ", e.Select(c => $"{c.ExternalSystemName}={c.IsAvailable}")))));

      Console.ReadKey();
      disposable.Dispose();
    }
        static void Main(string[] args)
        {
            AppDomain.CurrentDomain.UnhandledException += (sender, e) => Console.Error.WriteLine(e.ExceptionObject);

            if (args.Length >= 0)
            {
                JsConfig.DateHandler = JsonDateHandler.ISO8601;

                string host = args.Length == 0 ? "localhost" : args.First();

                var redisClient = new RedisClient(host);
                var temprc = redisClient.As<TemperatureItem>();
                var rtempList = temprc.Lists["tempatureReadings"];

                //Console.WriteLine(temprc.GetAllItemsFromList(rtempList).First().Timestamp);
                //Console.WriteLine(temprc.GetAllItemsFromList(rtempList).Last().Temperature);

                Console.WriteLine(string.Join("\n", UsbTEMPer.FindDevices().ToArray()));
                var xs = new ObservableUsbTemper();
                var temps = xs.TemperatureStreamFarenheight
                              .Timestamp()
                              .Do(ts => Console.WriteLine(ts));

                var sub = temps.Select(TemperatureItem.FromTDS)
                               .Subscribe(tst => temprc.AddItemToList(rtempList, tst), Console.Error.WriteLine, () => { });

                var disp = new CompositeDisposable(xs, redisClient, sub);
                Console.ReadKey();
                disp.Dispose();
            }
            else
            {
                ServiceBase.Run(new ServiceBase[]
                {
                    new TempLoggerService()
                });
            }
        }
Beispiel #11
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(".");
        }
 /// <summary>
 /// We need to create a new CompositeDisposable, as once a CompositeDisposable is Disposed
 /// it is useless, and we must recreate it
 /// </summary>
 public static void CreateNewCompositeDisposable(ref CompositeDisposable compositeDisposable)
 {
     compositeDisposable.Dispose();
     compositeDisposable = new CompositeDisposable();
 }
        private static void StartEditing(ListView list, ListViewItem item, DocumentGroup group, Action<TextBox, bool> endEditingFn)
        {
            var edit = item.FindDescendant<TextBox>();

            var visibility = Observable.FromEventPattern<DependencyPropertyChangedEventArgs>(edit, "IsVisibleChanged");

            var disposables = new CompositeDisposable();

            visibility.Where(re => re.EventArgs.NewValue as bool? == false)
                      .Take(1)
                      .Subscribe(re => disposables.Dispose());

            visibility.Where(ivc => ivc.EventArgs.NewValue as bool? == true)
                      .Take(1)
                      .Subscribe(re =>
                                 {
                                     edit.SelectionStart = 0;
                                     edit.SelectionLength = edit.Text.Length;
                                     edit.Focus();
                                 });

            disposables.Add(Observable.FromEventPattern<RoutedEventArgs>(edit, "LostFocus")
                                      .Take(1)
                                      .Subscribe(re => endEditingFn(edit, false)));

            disposables.Add(Observable.FromEventPattern<KeyEventArgs>(edit, "PreviewKeyUp")
                                      .Where(re => re.EventArgs.Key == Key.Escape || re.EventArgs.Key == Key.Enter)
                                      .Take(1)
                                      .Subscribe(re =>
                                                 {
                                                     re.EventArgs.Handled = true;
                                                     endEditingFn(edit, re.EventArgs.Key == Key.Escape);
                                                 }));

            disposables.Add(Observable.FromEventPattern<MouseEventArgs>(list, "MouseLeftButtonDown")
                                      .Take(1)
                                      .Subscribe(re => endEditingFn(edit, false)));

            group.StartEditing();
        }
        public void TextViewCreated(IWpfTextView textView)
        {
            var textBuffer = textView.TextBuffer;

            _openTextViewList.Add(textView);

            var changed = Observable.FromEventPattern<TextContentChangedEventArgs>(x => textBuffer.Changed += x, x => textBuffer.Changed -= x);

            var disp = changed
                .Select(_ => Unit.Default)
                .Multicast(_changed)
                .Connect();

            #if FALSE
            // NB: This feature is too f****d right now
            var disp = new CompositeDisposable(
                changed
                    .Select(_ => Unit.Default)
                    .Multicast(_changed)
                    .Connect(),
                changed.Buffer(() => changed.Throttle(TimeSpan.FromSeconds(2.0), RxApp.TaskpoolScheduler))
                    .ObserveOn(RxApp.MainThreadScheduler)
                    .TakeWhile(_ => textBuffer.CheckEditAccess()) // NB: Kill this if we can't access from the main thread
                    .Subscribe(x => {
                        // Tracking the changes themselves is Hard, because
                        // changes can modify themselves (i.e. you can hit space,
                        // then backspace). Instead, we're going to try to figure
                        // out the entire region that has changed, then apply
                        // trimming to the entire thing, brute force style.
                        var changesWithArgs = x.SelectMany(y =>
                            y.EventArgs.Changes.Select(z => new { Change = z, EventArgs = y.EventArgs }));

                        var minMax = changesWithArgs.Aggregate(new int?[2], (acc, y) => {
                            var smallestInThisChange = Math.Min(y.Change.NewSpan.Start, y.EventArgs.After.GetLineFromPosition(y.Change.NewSpan.Start).Start.Position);
                            var largestInThisChange = Math.Max(y.Change.NewSpan.End, y.EventArgs.After.GetLineFromPosition(y.Change.NewSpan.End).End.Position);

                            acc[0] = Math.Min(acc[0] ?? Int32.MaxValue, smallestInThisChange);
                            acc[1] = Math.Max(acc[1] ?? Int32.MinValue, largestInThisChange);

                            if (y.Change.LineCountDelta > 0) {
                                acc[1] = acc[1].Value + y.Change.LineCountDelta;
                            }

                            return acc;
                        });

                        // NB: I have no idea how this can happen, but it sure
                        // does, every time you edit a Razor view
                        if (!minMax[0].HasValue || !minMax[1].HasValue) return;

                        // Make triple sure we don't run off the end of the buffer
                        minMax[1] = Math.Min(minMax[1].Value, textBuffer.CurrentSnapshot.Length);

                        // NB: Sometimes, Visual Studio decides to submit the
                        // entire document as a "Change" when it really isn't.
                        // We're going to ignore this case even though sometimes
                        // it's actually legit (i.e. if the user pastes in the
                        // entire file).
                        if ((double)(minMax[1].Value - minMax[0].Value) / (double)textBuffer.CurrentSnapshot.Length > 0.9) {
                            return;
                        }

                        var span = textBuffer.CurrentSnapshot.CreateTrackingSpan(minMax[0].Value, minMax[1].Value - minMax[0].Value, SpanTrackingMode.EdgeInclusive).GetSpan(textBuffer.CurrentSnapshot);
                        var text = textBuffer.CurrentSnapshot.GetText(span);

                        if (!whitespaceRegex.IsMatch(text)) return;
                        textBuffer.Replace(span, whitespaceRegex.Replace(text, ""));
                    }));
            #endif

            textView.Closed += (sender, e) => {
                disp.Dispose();
                _openTextViewList.Remove(textView);
            };
        }
Beispiel #15
0
        public void CompositeDisposable_AddAfterDispose()
        {
            var disp1 = false;
            var disp2 = false;

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

            g.Dispose();
            Assert.IsTrue(disp1);
            Assert.AreEqual(0, g.Count); // CHECK

            g.Add(d2);
            Assert.IsTrue(disp2);
            Assert.AreEqual(0, g.Count); // CHECK

            Assert.IsTrue(g.IsDisposed);
        }
Beispiel #16
0
        private void RunTwoScheduleAsync(DateTime start, Func<CalculatedPropertyHelper, Task<int>> calculate1, Func<int> calculate2)
        {
            IScheduler eventLoopScheduler = new EventLoopScheduler();
            Console.WriteLine(this.GetElapsedTimeString(start) + ": Running on thread: " + Thread.CurrentThread.ManagedThreadId);
            IObservable<int> observable1 = Observable.Create<int>(o =>
                {
                    IDisposable d = eventLoopScheduler.ScheduleAsync(async (scheduler, token) =>
                        {
                            await scheduler.Yield();
                            o.OnNext(await calculate1(new CalculatedPropertyHelper(scheduler, token)));
                            o.OnCompleted();
                        });
                    return Disposable.Create(() =>
                        {
                            d.Dispose();
                            Console.WriteLine(this.GetElapsedTimeString(start) + ": Disposed!");
                        });
                });
            IObservable<int> observable2 = Observable.Create<int>(o =>
                {
                    IDisposable d = eventLoopScheduler.ScheduleAsync(async (scheduler, token) =>
                        {
                            o.OnNext(await Task.FromResult(calculate2()));
                            o.OnCompleted();
                        });
                    return Disposable.Create(() =>
                        {
                            d.Dispose();
                            Console.WriteLine(this.GetElapsedTimeString(start) + ": Disposed!");
                        });
                });
            Console.WriteLine(this.GetElapsedTimeString(start) + ": Subscribing.");
            CompositeDisposable s = new CompositeDisposable();
            for (int i = 0; i < 8; i++)
            {
                s.Add(observable1.Subscribe(Console.WriteLine, () => Console.WriteLine(this.GetElapsedTimeString(start) + ": Completed 1.")));
            }

            //for (int i = 0; i < 8; i++)
            //{
            //    s.Add(observable2.Subscribe(Console.WriteLine, () => Console.WriteLine(GetElapsedTimeString(start) + ": Completed 2.")));
            //}
            Console.WriteLine(this.GetElapsedTimeString(start) + ": Subscribed.");
            Thread.Sleep(1700);
            s.Dispose();
            Console.WriteLine(this.GetElapsedTimeString(start) + ": Should have disposed.");
            Thread.Sleep(2000);
            Console.WriteLine(this.GetElapsedTimeString(start) + ": Done.");
        }
Beispiel #17
0
 private void RunScheduleAsync(Func<Func<SchedulerOperation>, Task<int>> calculate)
 {
     Console.WriteLine("Running on thread: " + Thread.CurrentThread.ManagedThreadId);
     IObservable<int> observable = Observable.Create<int>(o =>
         {
             IDisposable d = new NewThreadScheduler().ScheduleAsync(async (scheduler, token) =>
                 {
                     o.OnNext(await calculate(scheduler.Yield));
                     o.OnCompleted();
                 });
             return Disposable.Create(() =>
                 {
                     d.Dispose();
                     Console.WriteLine("Disposed!");
                 });
         });
     Console.WriteLine("Subscribing.");
     CompositeDisposable s = new CompositeDisposable();
     for (int i = 0; i < 12; i++)
     {
         s.Add(observable.Subscribe(Console.WriteLine, () => Console.WriteLine("Completed.")));
     }
     Console.WriteLine("Subscribed.");
     Thread.Sleep(700);
     s.Dispose();
     Console.WriteLine("Should have disposed.");
     Thread.Sleep(2000);
     Console.WriteLine("Done.");
 }
Beispiel #18
0
        /// <summary>
        /// Requests FreeSwitch shuts down the socket
        /// </summary>
        public Task Exit()
        {
            // we're not using the CancellationToken here because we want to wait until the reply comes back
            var command = "exit";

            Log.Trace(() => "Sending [{0}]".Fmt(command));

            lock (gate)
            {
                var tcs = new TaskCompletionSource<BasicMessage>();
                var subscriptions = new CompositeDisposable();

                subscriptions.Add(
                    Messages.Where(x => x.ContentType == ContentTypes.CommandReply)
                            .Take(1)
                            .Select(x => new CommandReply(x))
                            .Subscribe(
                                result =>
                                Log.Debug(
                                    () => "CommandReply received [{0}] for [{1}]".Fmt(result.ReplyText.Replace("\n", string.Empty), command)),
                                ex =>
                                    {
                                        Log.ErrorException("Error waiting for Command Reply to [{0}].".Fmt(command), ex);
                                        tcs.TrySetException(ex);
                                    }));

                subscriptions.Add(
                    Messages.Where(x => x.ContentType == ContentTypes.DisconnectNotice)
                            .Take(1)
                            .Timeout(
                                TimeSpan.FromSeconds(2),
                                Observable.Throw<BasicMessage>(new TimeoutException("No Disconnect Notice received.")))
                            .Subscribe(
                                x =>
                                    {
                                        Log.Info(() => "Disconnect Notice received [{0}]".Fmt(x.BodyText));
                                        tcs.TrySetResult(x);
                                    },
                                ex =>
                                    {
                                        Log.ErrorException("Error waiting for Disconnect Notice", ex);
                                        if (ex is TimeoutException)
                                        {
                                            tcs.TrySetResult(null);
                                        }
                                        else
                                        {
                                            tcs.TrySetException(ex);
                                        }
                                    },
                                () =>
                                    {
                                        subscriptions.Dispose();
                                        tcs.TrySetResult(null);
                                    }));

                SendAsync(Encoding.ASCII.GetBytes(command + "\n\n"), CancellationToken.None)
                    .ContinueOnFaultedOrCancelled(tcs, subscriptions.Dispose);

                return tcs.Task;
            }
        }
Beispiel #19
0
        /// <summary>
        /// マクロを開始
        /// </summary>
        /// <param name="code"></param>
        public void Start(IMacroCode code)
        {
            if (this.Engine != null)
            {
                throw new InvalidOperationException("Already running");
            }

            this.IsExecutingSubject.OnNext(true);
            this.IsPausingSubject.OnNext(false);

            var macroDisposables = new CompositeDisposable();
            var macro = new MacroEngine(this.Connaction).AddTo(macroDisposables);
            this.Engine = macro;

            macro.Status.Subscribe(y => this.MessageSubject.OnNext(y)).AddTo(macroDisposables);
            macro.LogState.Subscribe(y => this.LogStateSubject.OnNext(y)).AddTo(macroDisposables);

            this.Plugins.Engine = macro;

            //別スレッドで開始
            Task.Run(async () =>
            {
                macro.Start(code.Name);

                try
                {
                    await code.RunAsync(macro, this.Plugins);
                }
                catch (Exception e)// when (e is TimeoutException || e is OperationCanceledException)
                {
                    this.ErrorSubject.OnNext(e.GetType().FullName + ": " + e.Message);
                }
                //catch (Exception e)
                //{
                //    this.ErrorSubject.OnNext(e.ToString());
                //}
                finally
                {
                    macro.End(code.Name);
                    macroDisposables.Dispose();
                    this.Engine = null;
                    this.IsExecutingSubject.OnNext(false);
                    this.IsPausingSubject.OnNext(false);
                    this.LogStateSubject.OnNext(true);
                }
            })
            .FireAndForget(e =>
            {
                this.ErrorSubject.OnNext("Error : " + e.GetType().FullName + ": " + e.Message);
            });
        }
Beispiel #20
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))));
        }
        public void TestServiceBusWithEmbeddedBroker()
        {
            // use the embedded broker
            var brokerUri = _broker.FailoverUri;

            // set up ServiceBus using fluent interfaces and all current endpoints and pointing at test AMQ broker
            IServiceBus serviceBus = ServiceBus.Configure()
                .WithActiveMQEndpoints<ITestMessage1>()
                    .Named("Obvs.TestService")
                    .UsingQueueFor<TestCommand>().ClientAcknowledge()
                    .UsingQueueFor<TestCommand2>().ClientAcknowledge()
                    .UsingQueueFor<IRequest>().AutoAcknowledge()
                    .ConnectToBroker(brokerUri)
                    .SerializedAsJson()
                    .AsClientAndServer()
                .PublishLocally()
                    .OnlyMessagesWithNoEndpoints()
                .UsingConsoleLogging()
                .Create();

            // create threadsafe collection to hold received messages in
            ConcurrentBag<IMessage> messages = new ConcurrentBag<IMessage>();

            // create some actions that will act as a fake services acting on incoming commands and requests
            Action<TestCommand> fakeService1 = command => serviceBus.PublishAsync(new TestEvent {Id = command.Id});
            Action<TestRequest> fakeService2 = request => serviceBus.ReplyAsync(request, new TestResponse {Id = request.Id});
            AnonymousObserver<IMessage> observer = new AnonymousObserver<IMessage>(messages.Add, Console.WriteLine, () => Console.WriteLine("OnCompleted"));

            // subscribe to all messages on the ServiceBus
            CompositeDisposable subscriptions = new CompositeDisposable
            {
                serviceBus.Events.Subscribe(observer),
                serviceBus.Commands.Subscribe(observer),
                serviceBus.Requests.Subscribe(observer),
                serviceBus.Commands.OfType<TestCommand>().Subscribe(fakeService1),
                serviceBus.Requests.OfType<TestRequest>().Subscribe(fakeService2)
            };
            
            // send some messages
            serviceBus.SendAsync(new TestCommand { Id = 123 });
            serviceBus.SendAsync(new TestCommand2 { Id = 123 });
            serviceBus.SendAsync(new TestCommand3 { Id = 123 });
            serviceBus.GetResponses(new TestRequest { Id = 456 }).Subscribe(observer);

            // wait some time until we think all messages have been sent and received over AMQ
            Thread.Sleep(TimeSpan.FromSeconds(1));

            // test we got everything we expected
            Assert.That(messages.OfType<TestCommand>().Count() == 1, "TestCommand not received");
            Assert.That(messages.OfType<TestCommand2>().Count() == 1, "TestCommand2 not received");
            Assert.That(messages.OfType<TestCommand3>().Count() == 1, "TestCommand3 not received");
            Assert.That(messages.OfType<TestEvent>().Count() == 1, "TestEvent not received");
            Assert.That(messages.OfType<TestRequest>().Count() == 1, "TestRequest not received");
            Assert.That(messages.OfType<TestResponse>().Count() == 1, "TestResponse not received");

            subscriptions.Dispose();
            ((IDisposable)serviceBus).Dispose();
            // win!
        }