WPF CosmosDB ReadNextAsync() hangs when is calling in background_worker

Viewed 280

In WPF I have background_worker and in it I have to make request to Cosmos DB, request that use iterator:

_worker_GenerateReport.DoWork += _worker_GenerateReport_DoWork;

This is method for backgroundWorker:

void _worker_GenerateReport_DoWork(object sender, DoWorkEventArgs e)
var result = QueryItemsAsync2(connectionString, queryToDownloadData.ToString());

And method. In this method on GetAwaiter().GetResult(); it hangs:

private async Task<IEnumerable<DTO_Proj>> QueryItemsAsync2(
    ConnectionString connectionString, string sqlQueryText)
{
    QueryDefinition queryDefinition = new QueryDefinition(sqlQueryText);
    var container = cosmosClient.GetContainer(connectionString.DatabaseID, 
        connectionString.Collection);
    
    FeedIterator<DTO_Proj> resultSet = 
        container.GetItemQueryIterator<DTO_Proj>(queryDefinition,
            requestOptions: new QueryRequestOptions()
            {
                //MaxItemCount = 1000,
                MaxConcurrency = 1
            });
    
    while (resultSet.HasMoreResults)
    {
        Task<FeedResponse<DTO_Proj>> response = resultSet.ReadNextAsync();
        var result = response.GetAwaiter().GetResult();
    }
}

I have to write once again. I removed BackgroundWorker and I see that the problem is with fetching items from CosmosDB. Now I have in xaml button:

<Button VerticalAlignment="Bottom" Grid.Row="1" HorizontalAlignment="Left"   Command="{Binding Path=Command_GenerateReport2}" IsEnabled="{Binding Path=IsUIEnabled, UpdateSourceTrigger=PropertyChanged}">report2</Button>

in MVVM command is created as follow:

Command_GenerateReport2 = new MVVM.RelayCommand(p => Can_GenerateReport(), a => generateReport2());

Method generateReport2:

  private void generateReport2()
  {
       ConnectionString connectionString = CreateConnectionStringAzureDB(serverToUse);

       string queryTest = " SELECT * FROM c WHERE c.Proj = 2544912 ";

       var result = QueryItemsAsync2(connectionString, queryTest);
   }

And method QueryItemsAsync2:

private async Task<IEnumerable<DTO_Proj>> QueryItemsAsync2(ConnectionString connectionString, string sqlQueryText)
  {
            QueryDefinition queryDefinition = new QueryDefinition(sqlQueryText);

            var container = cosmosClient.GetContainer(connectionString.DatabaseID, connectionString.Collection);

            FeedIterator<DTO_Proj> resultSet = container.GetItemQueryIterator<DTO_Proj>(
                queryDefinition,
                requestOptions: new QueryRequestOptions()
                {
                    MaxItemCount = 1000,
                    MaxConcurrency = 1
                });

    while (resultSet.HasMoreResults)
                {
                    Task<FeedResponse<DTO_Proj>> response = resultSet.ReadNextAsync();
                   
                    response.Wait();
...

And I have two CosmosDB containers. On one of them resultSet.ReadNextAsync() works and on the second hangs on this line. Configuration of these containers I think is the same. The difference is that on one container there is a lot of data and application hangs on it, on the second works but there is little data.

1 Answers

You should read the items asynchronously and not block by calling GetAwaiter().GetResult():

while (resultSet.HasMoreResults)
{
    var item = await resultSet.ReadNextAsync();
    ...
}

Then you don't need to use a BackgroundWorker or involve any background threads. You could simply call and await the asynchronous QueryItemsAsync2 method:

var result = await QueryItemsAsync2(connectionString, queryToDownloadData.ToString());
Related