0

I have an issue with the following code, working well in a Console App project and not working in a ASP.NET Web Forms project, both targeting .NET Framework 4.7.2.

The goal is to use the last Azure Cosmos DB SDK (v3) to get all documents in a container, without specifying a type (use of dynamic).

I've tried to target both the emulator (the last version 2.4.5) and the Azure Cosmos service.

In the ASP.NET project, the execution of queryResultSetIterator.ReadNextAsync().Result never ends (no timeout).

string endpointUri = "https://localhost:8081";
string primaryKey = "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==";
string database = "SendGridEvents";
string collection = "SendGridEvents";
using (CosmosClient client = new CosmosClient(endpointUri, primaryKey))
{
    Container container = client.GetDatabase(database).GetContainer(collection);

    QueryDefinition queryDefinition = new QueryDefinition("SELECT * FROM c");
    FeedIterator<dynamic> queryResultSetIterator = container.GetItemQueryIterator<dynamic>(queryDefinition);
    List<dynamic> documents = new List<dynamic>();
    while (queryResultSetIterator.HasMoreResults)
    {
        FeedResponse<dynamic> currentResultSet = queryResultSetIterator.ReadNextAsync().Result;
        foreach (var document in currentResultSet)
        {
            documents.Add(document);
        }
    }
}
Benjamin Talmard
  • 1,773
  • 11
  • 21

1 Answers1

2

This is caused due to a deadlock because of the use of the problematic .Result.

There are countless of sources that explain this deadlock but I will link this answer from StackOverflow.

The TL;DR is that you are blocking an otherwise asynchronous call in the UI thread which is causing the deadlock. You need to properly await your call like this:

FeedResponse<dynamic> currentResultSet = await queryResultSetIterator.ReadNextAsync();

You could technically block the call if you used the ConfigureAwait(false) approach but the v3 SDK does not cascade this call all the way to the network calls so it wouldn't make any difference. WebForms allows you to have async handlers so you would be fine to make your method async and try again.

Nick Chapsas
  • 6,872
  • 1
  • 20
  • 29
  • Thanks for the explanation. Make everything async was my first plan but I was thinking that ASP.NET 4.5 Model Binding mechanism doesn't support async. I was wrong as it works since 4.6. Cf https://devblogs.microsoft.com/aspnet/cool-asp-net-web-forms-features-in-2015-async-model-binding/ – Benjamin Talmard Aug 22 '19 at 13:14
  • Also, please, do not use `using`. Maintain a Singleton instacce of the CosmosClient across the lifetime of your application. – Matias Quaranta Aug 22 '19 at 18:44
  • Actually, this is the only call to the CosmosDB client in the HttpRequest so I can't share it but thanks for the advice. – Benjamin Talmard Aug 22 '19 at 21:07