【问题标题】:Task "not yet computed": An asynchronous module or handler completed while an asynchronous operation was still pending任务“尚未计算”:异步模块或处理程序已完成,而异步操作仍处于挂起状态
【发布时间】:2013-11-28 16:53:15
【问题描述】:

一直在优化客户端搜索功能,以便他可以一次执行多个搜索而不会影响加载时间(至少不会太多)。 搜索的工作方式是,我们首先获取外部服务的 json,将其转换为数据合同,然后将其保存在我们的数据库中并返回实体对象。

以前,我在一个方法中完成了所有这些,并成功地异步加载了多个搜索,但后来我认为,如果我可以将获取 json 的服务调用与将其保存到我们自己的数据库并返回对象的部分分开,那么它因为搜索服务实际上是真正的搜索,所以应该能够走得更快。

所以现在我有两个 OperationContract:

    [OperationContract]
    SwepubHeader DoSwepubSearchAdvanced(string searchQuery, string hiddenSearchWord, Dictionary<string, string> advancedSearchParameters);

    [OperationContract]
    List<List<SearchItem>> GetSearchResults(List<SwepubHeader> headers);

第一个进入名为 swepub 的搜索服务并检索 json 调用并将其解析为 DataContract 第二个将数据保存到数据库并将数据作为 EntityFramework 对象返回。用户可以发送多个 SwepubHeader-DataContract,然后得到多个搜索结果

在我要进行异步调用的网站中,我的代码如下所示:

    List<Task<SwepubHeader>> _taskList = new List<Task<SwepubHeader>>();

    public SwepubHeader[] DoSearchAdvanced(SwepubSearchServiceClient client, string query,
        string[] subQuerys, Dictionary<string, string> advancedSearchParameters)
    {
        _taskList = new List<Task<SwepubHeader>>();
        DoSearchAdvancedAsync(client, query, subQuerys, advancedSearchParameters);

        return _taskList.Select(task => task.Result).ToArray();
    }
    private async void DoSearchAdvancedAsync(SwepubSearchServiceClient client, string query, IEnumerable<string> subQuerys, Dictionary<string, string> advancedSearchParameters)
    {
        foreach (string subQuery in subQuerys)
        {
            if (!string.IsNullOrWhiteSpace(subQuery))
            {
                // Starts an async search
                _taskList.Add(client.DoSwepubSearchAdvancedAsync(query, subQuery,
                    advancedSearchParameters));
            }
        }
        // Awaits all async searches to finish
        await Task.WhenAll(_taskList);
    }

代码失败:

return _taskList.Select(task => task.Result).ToArray();

我错过了什么?所有 task.Result 将显示“尚未计算”。这可能与我在 DoSwepubSearchAdvanced 中执行 HttpWebRequests 有关吗?

【问题讨论】:

    标签: c# wcf entity-framework asynchronous .net-4.5


    【解决方案1】:

    您看到的问题是由于您使用了async void。作为一般规则,您应该避免使用async voidsee my MSDN article for more information.

    您的设计中还有另一个问题:it's not a good idea to wrap asynchronous methods within synchronous methods。一旦你解决了async void 问题,你仍然会得到deadlock issues that I describe on my blog

    正确的解决方案是用异步方法替换DoSearchAdvanced

    public Task<SwepubHeader[]> DoSearchAdvancedAsync(
        SwepubSearchServiceClient client,
        string query, string[] subQuerys,
        Dictionary<string, string> advancedSearchParameters)
    {
      return Task.WhenAll(subQuerys
          .Where(subQuery => !string.IsNullOrWhiteSpace(subQuery))
          .Select(subQuery => client.DoSwepubSearchAdvancedAsync(
              query, subQuery, advancedSearchParameters)));
    }
    

    然后将你的网站调用修改为await的结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-30
      • 2013-03-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多