WPF CosmosDB ReadNextAsync() 在调用 background_worker 时挂起

WPF CosmosDB ReadNextAsync() hangs when is calling in background_worker

在 WPF 中我有 background_worker 并且在其中我必须向 Cosmos DB 发出请求,请求使用迭代器:

_worker_GenerateReport.DoWork += _worker_GenerateReport_DoWork;

这是 backgroundWorker 的方法:

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

还有方法。在 GetAwaiter().GetResult(); 上的这种方法中它挂起:

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();
    }
}

我又要写一遍了。我删除了 BackgroundWorker,我发现问题出在从 CosmosDB 中获取项目。 现在我有 xaml 按钮:

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

MVVM命令中创建如下:

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

方法生成报告 2:

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

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

       var result = QueryItemsAsync2(connectionString, queryTest);
   }

和方法 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();
...

我有两个 CosmosDB 容器。其中一个 resultSet.ReadNextAsync() 有效,第二个挂在这条线上。我认为这些容器的配置是相同的。不同之处在于,在一个容器上有很多数据并且应用程序挂在上面,在第二个容器上工作但数据很少。

您应该 异步读取项目 而不是通过调用 GetAwaiter().GetResult():

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

那么您就不需要使用 BackgroundWorker 或涉及任何后台线程。您可以简单地调用并等待异步 QueryItemsAsync2 方法:

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