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; }
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 (); } }
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() }); } }
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); }; }
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); }
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."); }
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."); }
/// <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; } }
/// <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); }); }
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! }