question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Support for CountAsync()

See original GitHub issue

Is your feature request related to a problem? Please describe. In version 2.x of the SDK, we were able to execute asynchronous calls for determining the count of a IQueryable. It seems like you can only perform this in a synchronous fashion in the current version of the SDK.

Describe the solution you’d like Support the CountAsync() LINQ syntax

Describe alternatives you’ve considered None, there doesn’t appear to be support for this currently.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:13 (9 by maintainers)

github_iconTop GitHub Comments

3reactions
wahyuencommented, Jul 25, 2019

@j82w Thanks for the response. We had a quick test with your above suggestion and had some interesting observations to share.

Test Scenarios:

  • DocumentClient with synchronous Count call
  • DocumentClient with asynchronous CountAsync call
  • CosmosClient with sychronous Count call
  • CosmosClient with above mentioned asychronous iterator async pattern Microsoft.Azure.DocumentDB.Core 2.5.1 Microsoft.Azure.Cosmos 3.0.0

Test Code

var feedOptions = new FeedOptions
{
	MaxBufferedItemCount = -1,
	MaxItemCount = -1,
	MaxDegreeOfParallelism = -1,
	EnableCrossPartitionQuery = true
};

var documentClientSyncCount = documentClient.CreateDocumentQuery<Image>(uri, feedOptions)
	.Count(x => x.Investigations.Contains(investigationKey));

Console.WriteLine($"DocumentClient.Count: {documentClientSyncCount} - {watch.Elapsed.TotalMilliseconds:0}ms");

watch.Restart();

var documentClientAsyncCount = await documentClient.CreateDocumentQuery<Image>(uri, feedOptions)
	.Where(x => x.Investigations.Contains(investigationKey)).CountAsync();

Console.WriteLine($"DocumentClient.CountAsync: {documentClientAsyncCount} - {watch.Elapsed.TotalMilliseconds:0}ms");

watch.Restart();

var queryRequestOptions = new QueryRequestOptions
{
	MaxBufferedItemCount = -1,
	MaxConcurrency = -1,
	MaxItemCount = -1
};

var cosmosSyncCount = imagesContainer.GetItemLinqQueryable<Image>(true, queryRequestOptions).Count(x => x.Investigations.Contains(investigationKey));
Console.WriteLine($"CosmosClient.Count: {cosmosSyncCount} - {watch.Elapsed.TotalMilliseconds:0}ms");

watch.Restart();

var cosmosAsyncCount = 0;
var countIterator = imagesContainer.GetItemLinqQueryable<Image>(false, queryRequestOptions).Where(x => x.Investigations.Contains(investigationKey))
	.ToFeedIterator();

while (countIterator.HasMoreResults)
{
	var response = await countIterator.ReadNextAsync();

	cosmosAsyncCount += response.Resource.Count();
}

Console.WriteLine($"CosmosClient.CountAsync: {cosmosAsyncCount} - {watch.Elapsed.TotalMilliseconds:0}ms");

Results

DocumentClient.Count: 1763 - 2035ms
DocumentClient.CountAsync: 1763 - 2779ms
CosmosClient.Count: 1763 - 955ms
CosmosClient.CountAsync: 1763 - 8112ms

Observations

  • surprisingly, even the DocumentClient.CountAsync() seems to be slower than the sync version
  • the above mentioned iterator pattern seems to be significantly worse in performance than the sync version
  • the current implemenation of Count on CosmosClient seems to be the faster of all so far!!

We ran in to this issue as we are attempting to port our current 2.x SDK code to the new 3.x SDK. From this perspective, we have a large number of cases where we wish to perform various counts to a number of collections and we will often firing these off using CountAsync and simply execute a await Task.WhenAll(tasks) call to wait for them to all return.

If it was possible, we’d love to see your proposal of CountAsync extension method, as we believe this is the most idiomatic syntax given where previous developers are migrating from. If the SDK could combine the performance of the current implementation of Count in an asynchronous manner, we would be very happy campers 😃

2reactions
mark-manticorecommented, Jul 31, 2019

With the newly released 3.1 SDK I’m now able to work around this issue with the following code.

var requestOptions = new QueryRequestOptions();
requestOptions.EnableScanInQuery = true;

var queryDefinition = _container.GetItemLinqQueryable<T>().Where(predicate).ToQueryDefinition();
var queryText = queryDefinition.QueryText.Replace("VALUE root", "VALUE COUNT(1)", StringComparison.OrdinalIgnoreCase);
var queryIterator = _container.GetItemQueryIterator<int>(queryText, null, requestOptions);
var response = await queryIterator.ReadNextAsync();
return response.Resource.FirstOrDefault();
Read more comments on GitHub >

github_iconTop Results From Across the Web

QueryableExtensions.CountAsync Method (System.Data. ...
Asynchronously returns the number of elements in a sequence.
Read more >
CA1828: Do not use CountAsync/LongCountAsync when ...
This rule flags the CountAsync and LongCountAsync LINQ method calls used to check if the collection has at least one element.
Read more >
c# - CountAsync() does not work even if the query returns ...
Before counting i had to make the query a list using .ToList() and now pagination works as expected! Thanks @simplygood for providing help....
Read more >
Use Microsoft.Playwright.Core.Locator.CountAsync in ...
Use the CountAsync method in Microsoft.Playwright.Core package in your next Playwright-dotnet project with LambdaTest Automation Testing Advisor.
Read more >
Asynchronous Querying
Marten adds extension methods to IQueryable for the asynchronous invocation of the common Linq operators: AnyAsync(); CountAsync(); MinAsync(); MaxAsync() ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found