本文整理汇总了C#中ConcurrentBag.Count方法的典型用法代码示例。如果您正苦于以下问题:C# ConcurrentBag.Count方法的具体用法?C# ConcurrentBag.Count怎么用?C# ConcurrentBag.Count使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类ConcurrentBag
的用法示例。
在下文中一共展示了ConcurrentBag.Count方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: RoundRobinShouldHandleMultiThreadedRollOver
public void RoundRobinShouldHandleMultiThreadedRollOver()
{
var selector = new DefaultPartitionSelector();
var bag = new ConcurrentBag<Partition>();
Parallel.For(0, 100, x => bag.Add(selector.Select(_topicA, null)));
Assert.That(bag.Count(x => x.PartitionId == 0), Is.EqualTo(50));
Assert.That(bag.Count(x => x.PartitionId == 1), Is.EqualTo(50));
}
示例2: GetService_can_be_accessed_from_multiple_threads_concurrently
public void GetService_can_be_accessed_from_multiple_threads_concurrently()
{
for (var i = 0; i < 30; i++)
{
var bag = new ConcurrentBag<MigrationSqlGenerator>();
var resolver = new MigrationsConfigurationResolver();
ExecuteInParallel(() => bag.Add(resolver.GetService<MigrationSqlGenerator>("System.Data.SqlClient")));
Assert.Equal(20, bag.Count);
foreach (var generator in bag)
{
Assert.IsType<SqlServerMigrationSqlGenerator>(generator);
Assert.Equal(19, bag.Count(c => generator != c));
}
}
}
示例3: A_partitioned_stream_can_be_mapped_at_query_time
public async Task A_partitioned_stream_can_be_mapped_at_query_time()
{
for (var i = 1; i <= 9; i++)
{
store.WriteEvents(
streamId: Guid.NewGuid().ToString(),
howMany: 10,
bucketId: i.ToString());
}
var partitionedStream = Stream.Partitioned<EventMessage, int, string>(async (q, p) =>
{
var bucketId = ((IStreamQueryValuePartition<string>) p).Value;
var streamsToSnapshot = store.Advanced.GetStreamsToSnapshot(bucketId, 0);
var streamId = streamsToSnapshot.Select(s => s.StreamId).Single();
var stream = NEventStoreStream.ByAggregate(store, streamId, bucketId);
var batch = await stream.CreateQuery(q.Cursor, q.BatchSize).NextBatch();
return batch;
}).Trace();
var domainEvents = partitionedStream.Map(es => es.Select(e => e.Body).OfType<IDomainEvent>());
// catch up
var catchup = domainEvents.DistributeAmong(Enumerable.Range(1, 10)
.Select(i => Partition.ByValue(i.ToString())),
batchSize: 2);
var receivedEvents = new ConcurrentBag<IDomainEvent>();
catchup.Subscribe(async b =>
{
foreach (var e in b)
{
receivedEvents.Add(e);
}
});
await catchup.RunUntilCaughtUp().Timeout();
receivedEvents.Count().Should().Be(90);
}
示例4: TokenAwarePolicyRoundRobinsOnLocalReplicas
public void TokenAwarePolicyRoundRobinsOnLocalReplicas()
{
var hostList = new List<Host>
{
//5 local nodes and 4 remote
TestHelper.CreateHost("0.0.0.1", "dc1"),
TestHelper.CreateHost("0.0.0.2", "dc1"),
TestHelper.CreateHost("0.0.0.3", "dc2"),
TestHelper.CreateHost("0.0.0.4", "dc2"),
TestHelper.CreateHost("0.0.0.5", "dc1"),
TestHelper.CreateHost("0.0.0.6", "dc1"),
TestHelper.CreateHost("0.0.0.7", "dc2"),
TestHelper.CreateHost("0.0.0.8", "dc2"),
TestHelper.CreateHost("0.0.0.9", "dc1")
};
var clusterMock = new Mock<ICluster>(MockBehavior.Strict);
clusterMock
.Setup(c => c.AllHosts())
.Returns(hostList)
.Verifiable();
clusterMock
.Setup(c => c.GetReplicas(It.IsAny<string>(), It.IsAny<byte[]>()))
.Returns<string, byte[]>((keyspace, key) =>
{
var i = key[0];
return hostList.Where(h =>
{
//The host at with address == k and the next one
var address = TestHelper.GetLastAddressByte(h);
return address == i || address == i + 1;
}).ToList();
})
.Verifiable();
var policy = new TokenAwarePolicy(new DCAwareRoundRobinPolicy("dc1", 2));
policy.Initialize(clusterMock.Object);
var firstHosts = new ConcurrentBag<Host>();
var k = new RoutingKey { RawRoutingKey = new byte[] { 1 } };
//key for host :::1 and :::2
var actions = new List<Action>();
const int times = 100;
for (var i = 0; i < times; i++)
{
actions.Add(() =>
{
var h = policy.NewQueryPlan(null, new SimpleStatement().SetRoutingKey(k)).First();
firstHosts.Add(h);
});
}
var parallelOptions = new ParallelOptions();
parallelOptions.TaskScheduler = new ThreadPerTaskScheduler();
parallelOptions.MaxDegreeOfParallelism = 1000;
Parallel.Invoke(parallelOptions, actions.ToArray());
Assert.AreEqual(times, firstHosts.Count);
//Half the times
Assert.AreEqual(times / 2, firstHosts.Count(h => TestHelper.GetLastAddressByte(h) == 1));
Assert.AreEqual(times / 2, firstHosts.Count(h => TestHelper.GetLastAddressByte(h) == 2));
clusterMock.Verify();
}
示例5: DCAwareRoundRobinPolicyTestInParallel
public void DCAwareRoundRobinPolicyTestInParallel()
{
var hostList = new List<Host>
{
TestHelper.CreateHost("0.0.0.1", "dc1"),
TestHelper.CreateHost("0.0.0.2", "dc2"),
TestHelper.CreateHost("0.0.0.3", "dc1"),
TestHelper.CreateHost("0.0.0.4", "dc2"),
TestHelper.CreateHost("0.0.0.5", "dc1"),
TestHelper.CreateHost("0.0.0.6", "dc2"),
TestHelper.CreateHost("0.0.0.7", "dc1"),
TestHelper.CreateHost("0.0.0.8", "dc2"),
TestHelper.CreateHost("0.0.0.9", "dc1"),
TestHelper.CreateHost("0.0.0.10", "dc2")
};
var localHostsLength = hostList.Count(h => h.Datacenter == "dc1");
const string localDc = "dc1";
var clusterMock = new Mock<ICluster>();
clusterMock
.Setup(c => c.AllHosts())
.Returns(hostList);
//Initialize the balancing policy
var policy = new DCAwareRoundRobinPolicy(localDc, 1);
policy.Initialize(clusterMock.Object);
var allHosts = new ConcurrentBag<Host>();
var firstHosts = new ConcurrentBag<Host>();
Action action = () =>
{
var hosts = policy.NewQueryPlan(null, null).ToList();
//Check that the value is not repeated
Assert.AreEqual(0, hosts.GroupBy(x => x)
.Where(g => g.Count() > 1)
.Select(y => y.Key)
.Count());
firstHosts.Add(hosts[0]);
//Add to the general list
foreach (var h in hosts)
{
allHosts.Add(h);
}
};
var actions = new List<Action>();
const int times = 100;
for (var i = 0; i < times; i++)
{
actions.Add(action);
}
TestHelper.ParallelInvoke(actions);
//Check that the first nodes where different
foreach (var h in hostList)
{
if (h.Datacenter == localDc)
{
Assert.AreEqual(times/localHostsLength, firstHosts.Count(hc => hc == h));
}
else
{
Assert.AreEqual(0, firstHosts.Count(hc => hc == h));
}
}
clusterMock.Verify();
}
示例6: Main
static void Main(string[] args)
{
Console.WriteLine("Crank v{0}", typeof(Program).Assembly.GetName().Version);
if (args.Length < 2)
{
Console.WriteLine("Usage: crank [url] [numclients]");
return;
}
ServicePointManager.DefaultConnectionLimit = Int32.MaxValue;
string url = args[0];
int clients = Int32.Parse(args[1]);
TaskScheduler.UnobservedTaskException += OnUnobservedTaskException;
var connections = new ConcurrentBag<Connection>();
var sw = Stopwatch.StartNew();
Task.Factory.StartNew(() =>
{
Parallel.For(0, clients, i =>
{
try
{
var connection = new Connection(url);
connection.Received += data =>
{
Console.WriteLine(data);
};
connection.Error += e =>
{
Console.WriteLine("ERROR: Client {0}, {1}", i, e.GetBaseException());
};
connection.Closed += () =>
{
Console.WriteLine("CLOSED: {0}", i);
};
connection.Start().Wait();
connections.Add(connection);
}
catch (Exception e)
{
Console.WriteLine("Failed to start client {0}. {1}", i, e);
}
});
Console.WriteLine("Started {0} connection(s).", connections.Count);
});
Console.WriteLine("Press any key to stop running...");
Console.Read();
sw.Stop();
Console.WriteLine("Total Running time: {0}s", sw.Elapsed);
Console.WriteLine("End point: {0}", url);
Console.WriteLine("Total connections: {0}", clients);
Console.WriteLine("Active connections: {0}", connections.Count(c => c.IsActive));
Console.WriteLine("Stopped connections: {0}", connections.Count(c => !c.IsActive));
}
示例7: LogAlwaysShouldBeThreadSafe
public void LogAlwaysShouldBeThreadSafe()
{
var bag = new ConcurrentBag<string>();
MockLogger.Setup(m => m.Error(It.IsAny<object>())).Callback<object>(msg => bag.Add(msg.ToString()));
MockLogger.Setup(m => m.Info(It.IsAny<object>())).Callback<object>(msg => bag.Add(msg.ToString()));
MockLogger.Setup(m => m.IsErrorEnabled).Returns(true);
var threads = new List<Thread>();
for (int threadNumber = 0; threadNumber < 20; threadNumber++)
{
if (threadNumber % 2 == 0)
{
threads.Add(new Thread(() =>
{
for (int i = 0; i < 10; i++)
{
Subject.LogError(() => "Foo");
}
}));
}
else
{
threads.Add(new Thread(() =>
{
for (int i = 0; i < 10; i++)
{
Subject.LogAlways(() => "Always");
}
}));
}
}
threads.ForEach(t => t.Start());
foreach (var thread in threads)
{
thread.Join();
}
Assert.AreEqual(200, bag.Count);
Assert.AreEqual(100, bag.Count(msg => msg == "Foo"));
Assert.AreEqual(100, bag.Count(msg => msg == "Always"));
}
示例8: TestWmtsRequestInParallel
public void TestWmtsRequestInParallel()
{
// arrange
var resourceUrls = CreateResourceUrls();
var request = new WmtsRequest(resourceUrls);
var urls = new ConcurrentBag<Uri>(); // List is not thread save
var tileInfo = new TileInfo {Index = new TileIndex(8938, 5680, "14")};
// act
var requests = new List<Func<Uri>>();
for (var i = 0; i < 150; i++) requests.Add(() => request.GetUri(tileInfo));
Parallel.ForEach(requests, r => urls.Add(r()));
// assert
var count = urls.Count(u => u.ToString() == "http://maps1.wien.gv.at/wmts/lb/farbe/google3857/14/5680/8938.jpeg");
Assert.True(count == 50);
}
示例9: TestForeach
public void TestForeach()
{
const int numValues = 100000;
Scheduler.WaitFor(WriteLotsOfValuesInBatch(Tangle, numValues, -1));
var keys = new List<int>();
for (int i = 0; i < numValues; i += 2)
keys.Add(i);
long startTime = Time.Ticks;
var bag = new ConcurrentBag<int>();
var fForeach = Tangle.ForEach(keys, (key, value) => bag.Add(value));
Scheduler.WaitFor(fForeach);
decimal elapsedSeconds = (decimal)(Time.Ticks - startTime) / Time.SecondInTicks;
Console.WriteLine(
"{0} values in ~{1:00.000} second(s) at ~{2:00000.00} values/sec.",
keys.Count, elapsedSeconds, keys.Count / elapsedSeconds
);
Assert.AreEqual(keys.Count, bag.Count());
Assert.AreEqual(
keys.OrderBy((k) => k).ToArray(),
bag.OrderBy((k) => k).ToArray()
);
}
示例10: DispatchesMessages
public void DispatchesMessages()
{
const int numberOfMessages = 1000;
var settings = new MessageDispatcherSettings();
settings.InputChannel.WithDefault(new InMemoryMessageChannel());
settings.InvalidChannel.WithDefault(new InMemoryMessageChannel());
settings.MessageProcessorTypes.WithDefault(new List<Type> { typeof(FakeMessageProcessor) });
settings.DurationOfDispatchingSlice.WithDefault(new TimeSpan(0, 0, 0, 0, 200));
settings.NumberOfMessagesToDispatchPerSlice.WithDefault(30);
_dispatcher.Configure(settings);
_dispatcher.Enable();
Assert.AreEqual(MessageDispatcherState.Enabled, _dispatcher.State);
_transport.Open();
var recordIds = new ConcurrentBag<Guid>();
var start = DateTime.Now;
for (var j = 0; j < numberOfMessages; j++)
{
var record = GetRecord();
_transport.Send(record);
recordIds.Add(record.Identifier);
}
Console.WriteLine("Sent 1000 messages in {0} ms", (DateTime.Now - start).TotalMilliseconds);
Console.WriteLine("Waiting for messages to be processed");
start = DateTime.Now;
Assert.AreEqual(numberOfMessages, recordIds.Count);
var numberOfMessagesProcessed = 0;
do
{
Thread.Sleep(200);
numberOfMessagesProcessed = recordIds.Where(id => _registry.GetPublicationRecord(id).Completed).Count();
Console.WriteLine("{0} messages processed", numberOfMessagesProcessed);
}
while (numberOfMessagesProcessed < recordIds.Count());
Console.WriteLine("Completed in {0} seconds", (DateTime.Now - start).TotalSeconds);
_dispatcher.Disable();
Assert.AreEqual(MessageDispatcherState.Disabled, _dispatcher.State);
Assert.IsTrue(FakeMessageProcessor.ProcessedAnyMessages);
}
示例11: Main
static void Main(string[] args)
{
Console.WriteLine("Crank v{0}", typeof(Program).Assembly.GetName().Version);
if (args.Length < 2)
{
Console.WriteLine("Usage: crank [url] [numclients] <batchSize> <batchInterval>");
return;
}
ServicePointManager.DefaultConnectionLimit = Int32.MaxValue;
_running = true;
string url = args[0];
int clients = Int32.Parse(args[1]);
int batchSize = args.Length < 3 ? 50 : Int32.Parse(args[2]);
int batchInterval = args.Length < 4 ? 500 : Int32.Parse(args[3]);
TaskScheduler.UnobservedTaskException += OnUnobservedTaskException;
var connections = new ConcurrentBag<Connection>();
var sw = Stopwatch.StartNew();
Task.Factory.StartNew(() =>
{
Console.WriteLine("Ramping up connections. Batch size {0}.", batchSize);
var rampupSw = Stopwatch.StartNew();
ConnectBatches(url, clients, batchSize, batchInterval, connections).ContinueWith(task =>
{
Console.WriteLine("Started {0} connection(s).", connections.Count);
Console.WriteLine("Setting up event handlers");
rampupSw.Stop();
Console.WriteLine("Ramp up complete in {0}.", rampupSw.Elapsed);
});
});
Console.WriteLine("Press any key to stop running...");
Console.Read();
sw.Stop();
_running = false;
Console.WriteLine("Total Running time: {0}", sw.Elapsed);
Console.WriteLine("End point: {0}", url);
Console.WriteLine("Total connections: {0}", clients);
Console.WriteLine("Active connections: {0}", connections.Count(c => c.IsActive));
Console.WriteLine("Stopped connections: {0}", connections.Count(c => !c.IsActive));
Console.WriteLine("Closing connection(s).");
foreach (var connection in connections)
{
connection.Stop();
}
}
示例12: ButtonGenerateClick
// button events
private void ButtonGenerateClick(object sender, EventArgs e)
{
// start logging
Program.Log.Write("\nGenerate Data: " + DateTime.Now.ToString("u"));
Program.Log.Write("Skip Missing Animations? " + this.checkBoxSkipMissingAnimations.Checked);
Program.Log.Write("Delete Old Data? " + this.checkBoxClearOldJson.Checked);
Program.Log.Write("Clear Favorites? " + this.checkBoxReseedFavorites.Checked);
// initialize variables
int validPoserCount;
int emptyPoserCount;
int poserPacksCount;
var removedPoserCount = 0;
var jsonOutputDirectory = this.skyrimDirectory + Resources.PoserHotkeysDataPath;
// ensure output directory exists
if (!Directory.Exists(jsonOutputDirectory))
{
Directory.CreateDirectory(jsonOutputDirectory);
}
// clear favorites...
if (this.checkBoxReseedFavorites.Checked)
{
var favoritesJson = Directory.GetFiles(jsonOutputDirectory, Resources.FavoritesJsonName);
if (favoritesJson.Length <= 0)
{
Program.Log.Write(Resources.FavoritesJsonName + " not found.");
}
else
{
removedPoserCount++;
Program.Log.Write("Deleting " + Resources.FavoritesJsonName);
File.Delete(favoritesJson.First());
}
}
// clear old data...
if (this.checkBoxClearOldJson.Checked)
{
foreach (var jsonFile in Directory.GetFiles(jsonOutputDirectory, "*.json")
.Where(jsonFile => !jsonFile.Contains(Resources.FavoritesJsonName)))
{
removedPoserCount++;
Program.Log.Write("Deleting " + jsonFile);
File.Delete(jsonFile);
}
}
// generate data...
using (var pleaseWaitMessage = new FormPleaseWaitMessage())
{
pleaseWaitMessage.Show(this);
pleaseWaitMessage.Update();
try
{
// get checked poser list
var checkedPosers = this.checkedListBoxPosers.CheckedItems.OfType<Poser>();
var checkedPosersList = checkedPosers as IList<Poser> ?? checkedPosers.ToList();
// extract all packs from all checked posers
var results = new ConcurrentBag<PopulatePacksResults>();
Parallel.ForEach(
checkedPosersList,
poser =>
{
results.Add(poser.PopulatePacks(this.checkBoxSkipMissingAnimations.Checked));
});
// log results
foreach (var result in results)
{
Program.Log.Write("\nPoser: " + result.PoserName);
Program.Log.Write("\tLoaded Packs: " + result.PacksAdded.Count);
Program.Log.Write("\tLoaded Pack Names: " + String.Join(", ", result.PacksAdded));
Program.Log.Write("\tLoaded Animations: " + result.AnimationsAdded.Count);
Program.Log.Write("\tMissing Animations: " + result.AnimationsMissing.Count);
Program.Log.Write("\tMissing Animations Names: " + String.Join(", ", result.AnimationsMissing));
}
// get summary counts
validPoserCount = results.Count(x => x.PacksAdded.Count > 0);
emptyPoserCount = results.Count(x => x.PacksAdded.Count <= 0);
poserPacksCount = results.Sum(x => x.PacksAdded.Count);
// write to disc
SeedFavoritesJson(jsonOutputDirectory);
WriteJson(checkedPosersList, jsonOutputDirectory);
Program.Log.Write("\nGeneration complete! " + DateTime.Now.ToString("u"));
}
catch (Exception exception)
{
Program.Log.Write("Fatal Error: " + exception.Message);
throw;
}
pleaseWaitMessage.Close();
}
// show summary
//.........这里部分代码省略.........
示例13: SampleConnections
private static void SampleConnections(CrankArguments arguments, ConcurrentBag<Connection> connections, TimeSpan elapsed)
{
var connecting = connections.Count(c => c.State == ConnectionState.Connecting);
var connected = connections.Count(c => c.State == ConnectionState.Connected);
var reconnecting = connections.Count(c => c.State == ConnectionState.Reconnecting);
var disconnected = connections.Count(c => c.State == ConnectionState.Disconnected);
Mark(arguments, (ulong)connecting, "Connections Connecting");
Mark(arguments, (ulong)connected, "Connections Connected");
Mark(arguments, (ulong)reconnecting, "Connections Reconnecting");
Mark(arguments, (ulong)disconnected, "Connections Disconnected");
var transportState = "";
if (connections.First().Transport.GetType() == typeof(AutoTransport))
{
transportState = String.Format(", Transport={0}ws|{1}ss|{2}lp",
connections.Count(c => c.Transport.Name.Equals("webSockets", StringComparison.InvariantCultureIgnoreCase)),
connections.Count(c => c.Transport.Name.Equals("serverSentEvents", StringComparison.InvariantCultureIgnoreCase)),
connections.Count(c => c.Transport.Name.Equals("longPolling", StringComparison.InvariantCultureIgnoreCase)));
}
Console.WriteLine(String.Format("[{0}] Connections: {1}/{2}, State={3}|{4}c|{5}r|{6}d",
elapsed,
connections.Count(),
arguments.NumClients,
connecting,
connected,
reconnecting,
disconnected)
+ transportState);
}
示例14: worker_DoWork
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker self = (BackgroundWorker)sender;
Config cfg = (Config)e.Argument;
CultureInfo ci = new CultureInfo("en-US");
int totalCount = 1;
int processedCount = 0;
int progressValue = 0;
List<Uri> products = new List<Uri>();
// walk through categories
Uri category = cfg.Uri;
while(category != null)
{
string content = null;
for (content = Web.GetContent(category); content == null; content = Web.GetContent(category))
{
self.ReportProgress(progressValue, CONNECTION_ERROR);
Console.WriteLine("Failed {0}", category);
Thread.Sleep(SLEEPING_TIME);
}
Console.WriteLine("Read {0}", category);
// get products
MatchCollection mc = RE.Products.Matches(content);
foreach (Match m in mc)
{
Uri prod = new Uri(category, new Uri(m.Groups[1].Value, UriKind.Relative));
totalCount++;
products.Add(prod);
}
// check the next page
Match np = RE.Page.Match(content);
if (np.Success)
{
category = new Uri(category, new Uri(np.Groups[1].Value, UriKind.Relative));
}
else
category = null;
progressValue = (int)(100.0f / totalCount * processedCount);
self.ReportProgress(progressValue, "Reading categories");
}
// walk through products
ConcurrentBag<Photo> photoStorage = new ConcurrentBag<Photo>();
Parallel.ForEach(products, product =>
{
string content = null;
for (content = Web.GetContent(product); content == null; content = Web.GetContent(product))
{
self.ReportProgress(progressValue, CONNECTION_ERROR);
Console.WriteLine("Failed {0}", product);
Thread.Sleep(SLEEPING_TIME);
}
Console.WriteLine("Read {0}", product);
// check global suitability of the product:
// skip this product in case when it is out of stock on Zappos
if (!RE.ZapposOutOfStock.IsMatch(content))
{
try
{
string brand = "";
string name = "";
float price = 0.0f;
float oldPrice = 0.0f;
string sku = "";
List<Photo> photoList = new List<Photo>();
List<string> sizeList = new List<string>();
Match brandname = RE.ZapposBrandName.Match(content);
if (brandname.Success)
{
brand = brandname.Groups[1].Value;
name = brandname.Groups[2].Value;
price = float.Parse(RE.ZapposPrice.Match(content).Groups[2].Value, ci.NumberFormat);
sku = RE.ZapposSku.Match(content).Groups[1].Value;
Match mop = RE.ZapposOldPrice.Match(content);
if (mop.Success)
{
oldPrice = float.Parse(mop.Groups[1].Value, ci.NumberFormat);
}
// get the Size's Id
Match mSI = RE.ZapposSizeId.Match(content);
if (mSI.Success)
{
string styleId = mSI.Groups[1].Value;
Regex reZapposSizeWrapper = RE.GetZapposSizeWrapper(styleId);
Match mSizeWrap = reZapposSizeWrapper.Match(content);
if (mSizeWrap.Success)
//.........这里部分代码省略.........
示例15: CannotRemoveTheSameSubscriptionConcurrently
public async Task CannotRemoveTheSameSubscriptionConcurrently(int concurrencyLevel, int nSubscriptions)
{
// arrange
var subscriptions = Enumerable.Range(1, nSubscriptions)
.Select(n => new Subscription("topic" + n, "endpoint" + n, "dummy"))
.ToArray();
// add the subscriptions so they can be removed
foreach (var subscription in subscriptions)
{
await this.store.AddSubscription(subscription);
}
// act & assert
// for each subscription, tries to add it concurrently
foreach (var subscription in subscriptions)
{
var tasks = new ConcurrentBag<Task<bool>>();
var subscriptionToAdd = subscription; //capture context
Parallel.For(0, concurrencyLevel, c =>
{
tasks.Add(this.store.RemoveSubscription(subscription));
});
await Task.WhenAll(tasks);
// ensures only one concurrent task was able to add the subscription
Assert.AreEqual(1, tasks.Count(t => t.Result == true));
}
}