public IObservable <Tuple <Target, Message> > Map <Source, Target>(IObservable <Tuple <Source, Message> > source, IDictionary <Source, Target> target_by_source) { return(RX.Create <Tuple <Target, Message> >(observer => { return source.Subscribe( source_node_message => { try { Target target_node; bool found_target; using (Concurrency.ReaderLock(_mutex)) { found_target = target_by_source.TryGetValue(source_node_message.Item1, out target_node); } if (found_target) { var target_node_message = Tuple.Create(target_node, source_node_message.Item2); observer.OnNext(target_node_message); } } catch (Exception error) { observer.OnError(error); } }, observer.OnError, observer.OnCompleted ); })); }
public void Test() { var lockParser = new InstanceLockParser <Model>(nameof(NStandard), x => x.Year, x => x.Month, x => x.Sex, x => "const"); var model = new Model { Year = 2012, Month = 4, }; var stopwatch = new Stopwatch(); stopwatch.Start(); var result = Concurrency.Run(resultId => { using (var _lock = lockParser.Parse(model).TryBegin(500)) { if (_lock.Value) { Thread.Sleep(1000); return("Entered"); } else { return("Timeout"); } } }, level: 2, threadCount: 2); stopwatch.Stop(); Assert.Equal(1, result.Values.Count(x => x == "Entered")); Assert.Equal(1, result.Values.Count(x => x == "Timeout")); Assert.True(stopwatch.ElapsedMilliseconds < 2000); }
public void UpdateConflictTest() { #if NETFX using (new TransactionHelper()) { Concurrency.DatabaseWins(new DbReaderWriter(new AdventureWorks()), new DbReaderWriter(new AdventureWorks()), new DbReaderWriter(new AdventureWorks())); } using (new TransactionHelper()) { Concurrency.ClientWins(new DbReaderWriter(new AdventureWorks()), new DbReaderWriter(new AdventureWorks()), new DbReaderWriter(new AdventureWorks())); } using (new TransactionHelper()) { Concurrency.MergeClientAndDatabase(new DbReaderWriter(new AdventureWorks()), new DbReaderWriter(new AdventureWorks()), new DbReaderWriter(new AdventureWorks())); } using (new TransactionHelper()) { Concurrency.SaveChanges(new AdventureWorks(), new AdventureWorks()); } #else Rollback((adventureWorks1, adventureWorks2, adventureWorks3) => Concurrency.DatabaseWins(new DbReaderWriter(adventureWorks1), new DbReaderWriter(adventureWorks2), new DbReaderWriter(adventureWorks3))); Rollback((adventureWorks1, adventureWorks2, adventureWorks3) => Concurrency.ClientWins(new DbReaderWriter(adventureWorks1), new DbReaderWriter(adventureWorks2), new DbReaderWriter(adventureWorks3))); Rollback((adventureWorks1, adventureWorks2, adventureWorks3) => Concurrency.MergeClientAndDatabase(new DbReaderWriter(adventureWorks1), new DbReaderWriter(adventureWorks2), new DbReaderWriter(adventureWorks3))); Rollback((adventureWorks1, adventureWorks2) => Concurrency.SaveChanges(adventureWorks1, adventureWorks2)); #endif }
public void Test() { var lockParser = new TypeLockParser(nameof(NStandard)); var stopwatch = new Stopwatch(); stopwatch.Start(); var result = Concurrency.Run(resultId => { using (var _lock = lockParser.Parse <TypeLockTest>().TryBegin(500)) { if (_lock.Value) { Thread.Sleep(1000); return("Entered"); } else { return("Timeout"); } } }, level: 2, threadCount: 2); stopwatch.Stop(); Assert.Equal(1, result.Values.Count(x => x == "Entered")); Assert.Equal(1, result.Values.Count(x => x == "Timeout")); Assert.True(stopwatch.ElapsedMilliseconds < 1900); }
public void DbOverrideSimpleBatchTest(int concurrencyCount) { string tmpFile = string.Empty; MultiDbData multiData; try { (tmpFile, multiData) = GetMultiDbData(); var flattened = Concurrency.FlattenOverride(multiData); int totalRowCount = flattened.Count(); double expectedChunks = Math.Ceiling((double)totalRowCount / (double)concurrencyCount); int lastBatchSize = totalRowCount; var output = Concurrency.ConcurrencyByInt(multiData, concurrencyCount); Assert.IsTrue(expectedChunks <= output[0].Count() && output[0].Count() >= expectedChunks - 1); Assert.AreEqual(concurrencyCount, output.Count()); // Assert.AreEqual(lastBatchSize, output.Last().Count()); } finally { if (File.Exists(tmpFile)) { File.Delete(tmpFile); } } }
public void ParseString(string text, IGUIFont font, SpecialCharacterFlags flags = SpecialCharacterFlags.None) { Length = 0; GlyphChar[] tmp = null; if (!String.IsNullOrEmpty(text) && font != null) { tmp = new GlyphChar[text.Length]; int w = 0; for (int i = 0; i < text.Length; i++) { GlyphChar g = font.GetGlyph(text [i], flags); w += g.Width; tmp [i] = g; } Width = w; Length = text.Length; } if (tmp == null) { tmp = new GlyphChar[0]; } if (m_Glyphs == null) // called from constructor { m_Glyphs = tmp; } else { Concurrency.LockFreeUpdate(ref m_Glyphs, tmp); } }
public void DetectConflictTest() { using (new TransactionScope()) { Concurrency.NoCheck(); } using (new TransactionScope()) { try { Concurrency.ConcurrencyCheck(); Assert.Fail(); } catch (DbUpdateConcurrencyException exception) { Trace.WriteLine(exception); } } using (new TransactionScope()) { try { Concurrency.RowVersion(); Assert.Fail(); } catch (DbUpdateConcurrencyException exception) { Trace.WriteLine(exception); } } }
private async Task OnNextAsync(Tuple <string, Message> item) { try { this.TraceMessage(true, item); if (this.IsSelf(item.Item1)) { this.Incoming.OnNext(item); } else if (!this.groupConfig.Settings.IsUseHttpTransportForInstanceCommunication) { ChannelFactory <IDxStoreInstance> factory = this.GetChannelFactory(item.Item1); await Concurrency.DropContext(WCF.WithServiceAsync <IDxStoreInstance>(factory, (IDxStoreInstance instance) => instance.PaxosMessageAsync(this.groupConfig.Self, item.Item2), null, default(CancellationToken))); } else { HttpRequest.PaxosMessage msg = new HttpRequest.PaxosMessage(this.nodeEndPoints.Self, item.Item2); string targetHost = this.groupConfig.GetMemberNetworkAddress(item.Item1); await HttpClient.SendMessageAsync(targetHost, item.Item1, this.groupConfig.Name, msg); } } catch (Exception ex) { if (GroupMembersMesh.Tracer.IsTraceEnabled(TraceType.ErrorTrace)) { GroupMembersMesh.Tracer.TraceError((long)this.identity.GetHashCode(), "{0}: OnNextAsync(Node:{1}, Msg:{2}) failed with {3}", new object[] { this.identity, item.Item1, item.Item2, ex }); } } }
// Throws an exception on error. public static void Start(string serverHost, int serverTcpPort, int serverUdpPort, string logfilePath) { _logger = new Logger(logfilePath); // open TCP socket Socket tcpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _logger.Log(string.Format("TCP connecting to {0}:{1}...", serverHost, serverTcpPort)); tcpSocket.Connect(serverHost, serverTcpPort); _logger.Log(string.Format("...TCP connected to {0}", Utils.IPAddressToString(tcpSocket.RemoteEndPoint))); _address = Utils.IPAddressToString(tcpSocket.LocalEndPoint); _logger.Log("starting UDP client..."); UdpClient udpClient = new UdpClient(serverHost, serverUdpPort); int clientUdpPort = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port; _logger.Log(string.Format("...started UDP client on port {0}", clientUdpPort)); _logger.Log("sending UDP port to server..."); Protocol.Send(tcpSocket, clientUdpPort); _logger.Log("...sent UDP port to server"); Concurrency.StartThread(() => UdpSender(udpClient), "client UDP sender", _logger); Concurrency.StartThread(() => UdpReceiver(udpClient), "client UDP receiver", _logger); Concurrency.StartThread(() => TcpSender(tcpSocket), "client TCP sender", _logger); Concurrency.StartThread(() => TcpReceiver(tcpSocket), "client TCP receiver", _logger); }
public void DetectConflictTest() { Rollback((adventureWorks1, adventureWorks2, adventureWorks3) => Concurrency.NoCheck(new DbReaderWriter(adventureWorks1), new DbReaderWriter(adventureWorks2), new DbReaderWriter(adventureWorks3))); Rollback((adventureWorks1, adventureWorks2) => { try { Concurrency.ConcurrencyCheck(new DbReaderWriter(adventureWorks1), new DbReaderWriter(adventureWorks2)); Assert.Fail(); } catch (DbUpdateConcurrencyException exception) { Trace.WriteLine(exception); } }); Rollback((adventureWorks1, adventureWorks2) => { try { Concurrency.RowVersion(new DbReaderWriter(adventureWorks1), new DbReaderWriter(adventureWorks2)); Assert.Fail(); } catch (DbUpdateConcurrencyException exception) { Trace.WriteLine(exception); } }); }
public void DetectConflictTest() { #if NETFX using (new TransactionHelper()) { Concurrency.NoCheck(new DbReaderWriter(new AdventureWorks()), new DbReaderWriter(new AdventureWorks()), new DbReaderWriter(new AdventureWorks())); } using (new TransactionHelper()) { try { Concurrency.ConcurrencyCheck(new DbReaderWriter(new AdventureWorks()), new DbReaderWriter(new AdventureWorks())); Assert.Fail(); } catch (DbUpdateConcurrencyException exception) { Trace.WriteLine(exception); } } using (new TransactionHelper()) { try { Concurrency.RowVersion(new DbReaderWriter(new AdventureWorks()), new DbReaderWriter(new AdventureWorks())); Assert.Fail(); } catch (DbUpdateConcurrencyException exception) { Trace.WriteLine(exception); } } #else Rollback((adventureWorks1, adventureWorks2, adventureWorks3) => Concurrency.NoCheck(new DbReaderWriter(adventureWorks1), new DbReaderWriter(adventureWorks2), new DbReaderWriter(adventureWorks3))); Rollback((adventureWorks1, adventureWorks2) => { try { Concurrency.ConcurrencyCheck(new DbReaderWriter(adventureWorks1), new DbReaderWriter(adventureWorks2)); Assert.Fail(); } catch (DbUpdateConcurrencyException exception) { Trace.WriteLine(exception); } }); Rollback((adventureWorks1, adventureWorks2) => { try { Concurrency.RowVersion(new DbReaderWriter(adventureWorks1), new DbReaderWriter(adventureWorks2)); Assert.Fail(); } catch (DbUpdateConcurrencyException exception) { Trace.WriteLine(exception); } }); #endif }
public void MatchServersToFixedBucket() { try { int targetBuckets = 3; int serverCount = 40; int minDbCount = 10; int maxDbCount = 500; Random rnd = new Random(); string tmpFile = string.Empty; MultiDbData multiData; try { for (int i = 0; i < 100; i++) { targetBuckets = rnd.Next(2, 90); serverCount = rnd.Next(targetBuckets + 1, 300); minDbCount = rnd.Next(10, 150); maxDbCount = rnd.Next(minDbCount + 1, 500); int[] matrix; (tmpFile, multiData) = CreateRandomizedMultiDbData(serverCount, minDbCount, maxDbCount, out matrix); //The real work var buckets = Concurrency.RecombineServersToFixedBucketCount(multiData, targetBuckets); //Numbers for comparisons var flattened = Concurrency.ConcurrencyByServer(multiData); var idealBucket = Math.Ceiling((double)flattened.Sum(c => c.Count()) / (double)targetBuckets); int maxBucket = flattened.Where(c => c.Count() <= idealBucket).Max(c => c.Count()); //exclude the buckets that were already above the ideal int medianBucket = flattened.OrderBy(c => c.Count()).ToList()[(flattened.Count() / 2) + 1].Count(); string message = $"Buckets: {targetBuckets}; Servers: {serverCount}; Matrix: {string.Join(",", matrix)}"; Assert.AreEqual(targetBuckets, buckets.Count(), message); Assert.IsTrue(buckets.Max(c => c.Count()) < maxBucket + (idealBucket * 1.2), message); var str = Concurrency.ConvertBucketsToConfigLines(buckets); if (File.Exists(tmpFile)) { File.Delete(tmpFile); } } } finally { if (File.Exists(tmpFile)) { File.Delete(tmpFile); } } } catch (OutOfMemoryException) { //GitHub actions sometimes will run out of memory running this test! } }
public async Task Test_await_Task_result() { var sut = new Concurrency(); // Also unlike Go's goroutine, Task can 'returns' result after the task completed. var result = await sut.BenchmarkSayAsync("Hi", TimeSpan.FromMilliseconds(5)); // note: there's always overhead to run async operations. Assert.True(result > TimeSpan.FromMilliseconds(25)); }
static TSagaData SetConcurrency <TSagaData>(Concurrency <TSagaData> result, ContextBag context) where TSagaData : IContainSagaData { if (!EqualityComparer <TSagaData> .Default.Equals(result.Data, default(TSagaData))) { context.Set("NServiceBus.Persistence.Sql.Concurrency", result.Version); } return(result.Data); }
public override Task ExecuteAsync(int instanceId, Proposal <string, DxStoreCommand> proposal) { return(Concurrency.RunSynchronously(delegate() { lock (this.locker) { this.ExecuteLocally(instanceId, proposal); } })); }
public void UpdateConflictTest() { Rollback((adventureWorks1, adventureWorks2, adventureWorks3) => Concurrency.DatabaseWins(new DbReaderWriter(adventureWorks1), new DbReaderWriter(adventureWorks2), new DbReaderWriter(adventureWorks3))); Rollback((adventureWorks1, adventureWorks2, adventureWorks3) => Concurrency.ClientWins(new DbReaderWriter(adventureWorks1), new DbReaderWriter(adventureWorks2), new DbReaderWriter(adventureWorks3))); Rollback((adventureWorks1, adventureWorks2, adventureWorks3) => Concurrency.MergeClientAndDatabase(new DbReaderWriter(adventureWorks1), new DbReaderWriter(adventureWorks2), new DbReaderWriter(adventureWorks3))); Rollback((adventureWorks1, adventureWorks2) => Concurrency.SaveChanges(adventureWorks1, adventureWorks2)); }
private static void AcceptTcpClients(Socket serverSocket) { while (true) { // accept client Socket clientSocket = serverSocket.Accept(); _logger.Log(string.Format("accepted client from {0}", Utils.IPAddressToString(clientSocket.RemoteEndPoint))); Concurrency.StartThread(() => HandleTcpClient(clientSocket), "server handle client", _logger); } }
public void TestSay_Task_runs_concurrently() { var sut = new Concurrency(); Task.Run(() => sut.Say("Hello", TimeSpan.FromMilliseconds(10))); sut.Say("World", TimeSpan.FromMilliseconds(1)); var output = sut.Logs.ToArray(); Assert.Equal(5, output.Length); Assert.Equal(5, output.Count(message => message.EndsWith("World"))); }
public void RefreshGlyphs(IGUIFont font, SpecialCharacterFlags flags) { GlyphList glyphs = new GlyphList(); foreach (GlyphChar g in Glyphs) { glyphs.AddLast(font.GetGlyph(g.Char, flags)); } Concurrency.LockFreeUpdate(ref m_Glyphs, glyphs); NeedsWordWrap = true; }
static TSagaData SetConcurrency <TSagaData>(Concurrency <TSagaData> result, ContextBag context) where TSagaData : IContainSagaData { // ReSharper disable once CompareNonConstrainedGenericWithNull //TODO: remove when core adds a class constraint to TSagaData if (result.Data == null) { return(default(TSagaData)); } context.Set("NServiceBus.Persistence.Sql.Concurrency", result.Version); return(result.Data); }
public void Test1() { var generator = new IdGenerator <string>(() => DateTime.Now.Ticks.ToString()); var level = 100; var result = Concurrency.Run(cid => { return(generator.TakeOne()); }, level: level); Assert.Equal(level, result.Count); Assert.Equal(level, result.Select(x => x.Value).Distinct().Count()); }
public void Test_wait_Task() { var sut = new Concurrency(); // Unlike Go's goroutine, Task has its state. var task = Task.Run(() => sut.Say("Hi", TimeSpan.FromMilliseconds(5))); // wait task completes with timeout. task.Wait(TimeSpan.FromSeconds(1)); var output = sut.Logs.ToArray(); Assert.True(output.All(message => message == "Hi")); }
void ResetCachedData() { Concurrency.LockFreeUpdate(ref m_SortedVisibleColumns, Columns.SortedVisibleColumns.ToArray()); var lst = new BinarySortedList <float> (); float offset = 0; Columns.Where(col => col.Visible).ForEach(col => { lst.AddLast(offset); offset += col.Width; }); Concurrency.LockFreeUpdate(ref m_ColumnOffsets, lst); }
public void LoadTextAsync(string value, float breakWidth) { BreakWidth = breakWidth; if (value == null) { value = String.Empty; } Task.Factory.StartNew(() => { Stopwatch sw = Stopwatch.StartNew(); int index = 0; Paragraphs.Clear(); ParagraphList paragraphs = new ParagraphList(LineHeight, BreakWidth); char splitChar = AutoDetectLineBreakChar(value); if (!GroupParagraphs) { Strings.Split(value, splitChar).ForEach(line => paragraphs.AddLast(new Paragraph(index++, BreakWidth, line, Font, Flags)) ); } else { const string splitStr = "\r\n\r\n"; Strings.Split(value, splitStr).ForEach(line => { paragraphs.AddLast(new Paragraph(index++, BreakWidth, line.Replace("\n", " ") + "\n", Font, Flags)); paragraphs.AddLast(new Paragraph(index++, BreakWidth, "\n", Font, Flags)); }); } paragraphs.OnUpdate(); Concurrency.LockFreeUpdate(ref m_Paragraphs, paragraphs); this.LogVerbose("{0} characters of text in {1} paragraphs loaded into the editor in {2} ms.", value.Length.ToString("n0"), Paragraphs.Count.ToString("n0"), sw.ElapsedMilliseconds.ToString("n0")); }).ContinueWith((t) => { if (t.Status == TaskStatus.RanToCompletion) { if (Paragraphs.BreakWidth != BreakWidth) { Paragraphs.OnUpdateBreakWidthAsync(BreakWidth); } } }).ContinueWith((t) => { Owner.UndoRedoManager.Clear(); if (LoadingCompleted != null) { LoadingCompleted(this, EventArgs.Empty); } }); }
public async Task Test_await_Task() { var sut = new Concurrency(); // async/await pattern is recommended over 'blocking' methods. // but it forces to reimplement all blocking methods as they return Task or Task<T> type. await sut.SayAsync("Hi", TimeSpan.FromMilliseconds(5)); // you can also mix Task.Run and blocking method though, it is not recommended. // await Task.Run(() => sut.Say("Hi", TimeSpan.FromMilliseconds(5))); var output = sut.Logs.ToArray(); Assert.True(output.All(message => message == "Hi")); }
private static void TcpSender(Socket socket) { while (true) { object obj = null; if (Concurrency.Dequeue(_tcpSendQueue, out obj)) { System.Type type = obj.GetType(); _logger.Log(string.Format("TCP sending object of type {0}...", type)); Protocol.Send(socket, obj); _logger.Log(string.Format("...TCP sent object of type {0}", type)); } } }
public void TestSay() { var sut = new Concurrency(); var duration = TimeSpan.FromMilliseconds(5); Task.Run(() => sut.Say("Hello", duration)); sut.Say("World", duration); // wait for task same as Go's. Thread.Sleep(duration); var output = sut.Logs.ToArray(); Assert.Equal(10, output.Length); Assert.Equal(5, output.Count(message => message.EndsWith("Hello"))); }
public void ConflictTest() { Concurrency.DefaultControl(); try { Concurrency.CheckModifiedDate(); Assert.Fail(); } catch (ChangeConflictException exception) { Trace.WriteLine(exception); } Concurrency.DatabaseWins(); Concurrency.ClientWins(); Concurrency.MergeClientAndDatabase(); }
public void InvertSelection() { int rowCount = RowCount; HashSet <int> sel = new HashSet <int> (); for (int i = 0; i < rowCount; i++) { if (!m_SelectedRowIndices.Contains(i)) { sel.Add(i); } } Concurrency.LockFreeUpdate(ref m_SelectedRowIndices, sel); OnSelectionChanged(); }
public void MatchServersToFixedBucket_ToConfigLines() { int targetBuckets = 3; int serverCount = 40; int minDbCount = 10; int maxDbCount = 500; Random rnd = new Random(); string tmpFile = string.Empty; MultiDbData multiData; try { for (int i = 0; i < 20; i++) { targetBuckets = rnd.Next(2, 51); serverCount = rnd.Next(targetBuckets + 1, 400); minDbCount = rnd.Next(10, 201); maxDbCount = rnd.Next(minDbCount + 1, 600); int[] matrix; (tmpFile, multiData) = CreateRandomizedMultiDbData(serverCount, minDbCount, maxDbCount, out matrix); var buckets = Concurrency.RecombineServersToFixedBucketCount(multiData, targetBuckets); var str = Concurrency.ConvertBucketsToConfigLines(buckets); string message = $"Buckets: {targetBuckets}; Servers: {serverCount}; Matrix: {string.Join(",", matrix)}"; Assert.AreEqual(buckets.Count(), str.Count(), message); for (int j = 0; j < buckets.Count(); j++) { Assert.AreEqual(buckets[j].Count(), str[j].Count(), message); Assert.AreEqual(buckets[j].First().Item1, str[j].First().Substring(0, str[j].First().IndexOf(":")), message); Assert.AreEqual(buckets[j].Last().Item1, str[j].Last().Substring(0, str[j].Last().IndexOf(":")), message); } if (File.Exists(tmpFile)) { File.Delete(tmpFile); } } } finally { if (File.Exists(tmpFile)) { File.Delete(tmpFile); } } }
/// <summary>Does the test.</summary> /// <param name="level">The level.</param> /// <param name="concurrency">The concurrency.</param> /// <param name="transactionMode">The transaction mode.</param> private void DoTest(MessageCount level, Concurrency concurrency, TransactionModeUtils.TransactionMode transactionMode) { var messageCount = (int)level; var concurrentConsumers = (int)concurrency; var transactional = transactionMode.IsTransactional(); var template = this.CreateTemplate(concurrentConsumers); var latch = new CountdownEvent(messageCount); for (var i = 0; i < messageCount; i++) { template.ConvertAndSend(queue.Name, i + "foo"); } var container = new SimpleMessageListenerContainer(template.ConnectionFactory); var listener = new LifecyclePocoListener(latch); container.MessageListener = new MessageListenerAdapter(listener); container.AcknowledgeMode = transactionMode.AcknowledgeMode(); container.ChannelTransacted = transactionMode.IsTransactional(); container.ConcurrentConsumers = concurrentConsumers; if (transactionMode.Prefetch() > 0) { container.PrefetchCount = transactionMode.Prefetch(); container.TxSize = transactionMode.TxSize(); } container.QueueNames = new[] { queue.Name }; container.AfterPropertiesSet(); container.Start(); try { var waited = latch.Wait(50); Logger.Info("All messages received before stop: " + waited); if (messageCount > 1) { Assert.False(waited, "Expected not to receive all messages before stop"); } Assert.AreEqual(concurrentConsumers, container.ActiveConsumerCount); container.Stop(); Thread.Sleep(500); Assert.AreEqual(0, container.ActiveConsumerCount); if (!transactional) { var messagesReceivedAfterStop = listener.Count; waited = latch.Wait(500); Logger.Info("All messages received after stop: " + waited); if (messageCount < 100) { Assert.True(waited, "Expected to receive all messages after stop"); } Assert.AreEqual(messagesReceivedAfterStop, listener.Count, "Unexpected additional messages received after stop"); for (var i = 0; i < messageCount; i++) { template.ConvertAndSend(queue.Name, i + "bar"); } latch = new CountdownEvent(messageCount); listener.Reset(latch); } var messagesReceivedBeforeStart = listener.Count; container.Start(); var timeout = Math.Min(1 + messageCount / (4 * concurrentConsumers), 30); Logger.Debug("Waiting for messages with timeout = " + timeout + " (s)"); waited = latch.Wait(timeout * 1000); Logger.Info("All messages received after start: " + waited); Assert.AreEqual(concurrentConsumers, container.ActiveConsumerCount); if (transactional) { Assert.True(waited, "Timed out waiting for message"); } else { var count = listener.Count; Assert.True(messagesReceivedBeforeStart < count, "Expected additional messages received after start: " + messagesReceivedBeforeStart + ">=" + count); Assert.Null(template.Receive(queue.Name), "Messages still available"); } Assert.AreEqual(concurrentConsumers, container.ActiveConsumerCount); } finally { // Wait for broker communication to finish before trying to stop // container Thread.Sleep(500); container.Shutdown(); Assert.AreEqual(0, container.ActiveConsumerCount); } Assert.Null(template.ReceiveAndConvert(queue.Name)); }