【问题标题】:Am I getting the benefits of async and await in the following code我是否在以下代码中获得了异步和等待的好处
【发布时间】:2016-08-24 20:25:07
【问题描述】:

我有以下代码,其中我在 GroupBy 子句中使用了 async 关键字,但是智能告诉我这个调用不会等待并将同步运行,我的问题是我对 GetAllLanguages 的两次调用和GetAllStores 和我随后对 Task.WaitAll(languagesTask, storesTask); 的调用使用异步功能,或者我的所有代码都会同步运行,因为我不等待 GroupBy 语句。也可以等待.GroupBy(async resourceApplicationType .. 电话。

 public async Task UpdateAllResources()
        {
            var applicationTypes = databaseSettings.Select(dbcs => dbcs.ResourceApplicationType);
            var commandsPerApplication = applicationTypes
                .GroupBy(async resourceApplicationType =>
                {
                    var languagesTask = GetAllLanguages(resourceApplicationType);
                    var storesTask = GetAllStores(resourceApplicationType);
                    var resourceCategory = ResourceApplicationToCategoriesMapper.Map(resourceApplicationType);
                    Task.WaitAll(languagesTask, storesTask);
                    var commands = from category in resourceCategory
                            from language in languagesTask.Result
                            from store in storesTask.Result
                            select new UpdateResourcesCommand
                            {
                                ApplicationType = resourceApplicationType,
                                StoreCode = store.Code,
                                LocaleCode = language.Locale,
                                ResourceCategory = category
                            };
                    return new
                    {
                        applicationType = resourceApplicationType, commands
                    };
                });

           commandsPerApplication.ForEach(commandsGroup =>
           {
               commandsGroup.Key.Result.commands.ForEach(async command =>
               {
                   await commandExecutor.Execute<UpdateResourcesCommand, Task>(command);
               });
           });
        }

        private Task<IEnumerable<Language>> GetAllLanguages(ResourceApplication applicationType)
        {
            return allLanguagesQueryRetriever.GetByComponentName(InstanceName.GetUniqueName<IAllLanguagesQuery>(applicationType.ToString()))
                .Execute(new AllLanguagesCriteria());
        }

        private Task<IEnumerable<Store>> GetAllStores(ResourceApplication applicationType)
        {
            return allStoresQueryRetriever
                .GetByComponentName(InstanceName.GetUniqueName<IAllStoresQuery>(applicationType.ToString()))
                .Execute(new AllStoresCriteria());
        }

【问题讨论】:

  • 您没有在 UpdateAllResources 函数中等待 Task.WaitAll(languagesTask, storesTask);。这可能意味着在您尝试访问结果之前任务尚未完成
  • @JLevett 该语句不可等待“类型 void 不可等待”,它本质上是在等待。
  • 我很抱歉。你也可以使用await Task.WhenAll()
  • 出于好奇,Threads 窗口 Debug-> Windows-> Threads 显示什么?

标签: c# linq async-await


【解决方案1】:

基本的经验法则是“没有等待,异步将同步运行”。

您可以通过将Task.WaitAll() 替换为await Task.WhenAll(),轻松让您的GroupBy() 正常运行async

【讨论】:

  • 在使用WhenAll之后,我仍然需要访问Result对象commandsGroup.Key.Result.commands.ForEach(async command =&gt;,这样可以吗?我会想如果我真的等待一切,那么我可以绕过调用 Result?!
  • 不幸的是,这仅在您等待单个任务并将其结果直接分配给变量时才有效,例如var languages = await GetAllLanguages()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-09
  • 2014-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多