2016-08-24 1 views
0

다음 코드는 내 GroupBy 절에서 비동기 키워드를 사용하지만 intellisence가이 호출을 기다리지 않고 동 기적으로 실행한다고 말합니다 내 질문은 GetAllLanguagesGetAllStores 내 두 호출 및 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()); 
     } 
+0

당신은'Task.WaitAll (languagesTask, storesTask)를 기다리고하지 않는 UI thread/Synchronization context 블록으로, Task.WaitAll()로 교착 상태에 바인딩되어'에 'UpdateAllResources' 함수입니다. 그 결과는 당신이 결과에 접근하기 전에 끝나지 않았 음을 의미 할 수 있습니다. – JConstantine

+0

@JLevett 그 진술은 기다릴 수 없습니다. "Type void는 기다릴 수 없습니다", 그것은 본질적으로 기다리고 있습니다. – Xerxes

+0

사과드립니다. 'await Task.WhenAll()'을 사용할 수도 있습니다. – JConstantine

답변

0

기본 규칙은 "기다리지 않고 비동기가 동 기적으로 실행됩니다."입니다.

당신은 쉽게 GroupBy()await Task.WhenAll()에 대한 Task.WaitAll()를 교환하여 제대로 async를 실행 얻을 수 있습니다. async 코드로 인해 await 키워드 비 사용에 확실히 Synchronously을 실행하는 이유 초점이 여기에 불구하고

+0

나는 여전히 ResultAll을 사용하고 난 후에 결과 객체'commandsGroup.Key.Result.commands.ForEach (async command =>')를 처리해야한다. 만약 내가 모든 것을 기다렸다면 결과를 호출 할 수 없다. ?! – Xerxes

+0

불행히도, 개별 작업을 기다리고 결과를 직접 변수에 할당하는 경우에만 작동합니다 (예 :'var languages ​​= GetAllLanguages ​​()'를 기다리는 중). – JConstantine

0

코드는 여기에서 밖으로 인해 잘못된 async-await 사용에 주변에 숨어 더 큰 문제를 가지고 있지만, 설명으로 만 될 수 있습니다 Task에있는 경우 void이 아닌 경우 Task.WhenAll()이 필요합니다.

GetAllLanguagesGetAllStores은 IO 묶음이 async이 아닌데 놀랍습니다. 경우

당신이 코드 Synchronously를 실행할 계획하고 특히 Console application을 제외하고 아무거나 UI Synchronization context을 필요로하는 코드에 대한 때문에 Task.WaitAll()에 교착 상태가 될 것이다. Synchronous manner 기다렸다 경우 Task을 반환하는 비동기 방식 한마디로

자체

관련 문제