2016-07-11 5 views
2

아래 코드를 붙여 넣었습니다. 유형 'System.IO.FileNotFoundException'형식의 예외가 발생비동기 GetAwaiter() 이상한 예외를 던지고

:이 예외로 결과를 얻는 경우가 던져 mapPromise.GetAwaiter()에 내가 마지막 줄에 awaitable 전화 Task<IEnumerable<SkuGcn>> GetSkuGcnList();를 호출 신체의 첫 번째 줄에 System.Private.CoreLib.ni.dll하지만 사용자 코드에서 처리되지 않았습니다.

추가 정보 : 파일 또는 어셈블리를로드 할 수 없습니다. 'System.Runtime.Serialization.Xml, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a '. 시스템이 지정된 파일을 찾을 수 없습니다.

은 내가 브레이크 포인트를 설정할 수 있기 때문에 GetSkuGcnList() 전화가 호출 내 서비스는, 호출되는 알고 통화가 이루어질 때 나는 그것을 휴식. 그렇다면 서비스가 돌아온 것 같습니다.

이 코드는 ASP.NET 5 RC1에서 제대로 작동하지만 ASP.Net Core 1.0 릴리스에서는 그리 좋지 않습니다.

도움이 될 것입니다.

 public ProductItemsCacheStore(IItemsProductCacheRepository itemsRepo, IProductAvailabilityPricing proxyGoliathApi, 
     IProductItemListRepo itemsListsRepo, IItemPricesCacheRepo itemPricesRepo) 
     { 
      var mapPromise = proxyGoliathApi.GetSkuGcnList(); 
      _items = itemsRepo.GetAllProductOrderListForCache(); 
      _itemsLists = itemsListsRepo.GetItemListsForCache(); 
      _priceZones = itemPricesRepo.GetAllPriceZonesAndItemPrices(); 
      MergeProductsWithGcn(_items, mapPromise.GetAwaiter().GetResult()); 
     } 

내 project.json은 다음과 같습니다

{ 
    "version": "1.0.0-alpha.1", 
    "description": "AvailabilityPricingClient Class Library", 
    "authors": [ "irving.lennert" ], 
    "packOptions": { 
    "tags": [ "" ], 
    "projectUrl": "", 
    "licenseUrl": "" 
    }, 

    "tooling": { 
    "defaultNamespace": "AvailabilityPricingClient" 
    }, 

    "dependencies": { 
    "Microsoft.NETCore.App": { 
     "version": "1.0.0", 
     "type": "platform" 
    }, 
    "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0", 
    "Microsoft.AspNetCore.Server.Kestrel": "1.0.0", 
    "Microsoft.Extensions.Configuration.Json": "1.0.0", 
    "Microsoft.Extensions.Logging": "1.0.0", 
    "Microsoft.Extensions.Logging.Console": "1.0.0", 
    "Microsoft.Extensions.Logging.Debug": "1.0.0", 
    "Microsoft.AspNet.WebApi.Client": "5.2.3" 
    }, 

    "frameworks": { 
    "netcoreapp1.0": { 
     "imports": [ 
     "dotnet5.6", 
     "portable-net45+win8" 
     ] 
    } 
    } 
} 

GetSkuGcnList()의 구현은 이것이다 :

public async Task<IEnumerable<SkuGcn>> GetSkuGcnList() 
    { 
     HttpResponseMessage response = _client.GetAsync("/api/skuGcnList").Result; 

     if (response.IsSuccessStatusCode) 
     { 
      var skuGcns = await response.Content.ReadAsAsync<IEnumerable<SkuGcn>>(); 
      return skuGcns; 
     } 

     return null; 
    } 
+0

'mapPromise.GetAwaiter(). GetResult()'는 매우 이상합니다. 'ProductItemsCacheStore'를 비동기로 만들거나'GetSkuGcnList'를 동기로 만들어서 태스크를 반환하지 않을 수 있습니까? 동기화 및 비동기 혼합 항상 문제가 발생 –

+0

문제는 코드가 아니라 project.json 구성에 있다고 가정합니다. project.json의 nugets 참조 및 런타임 구성은 문제의 근원을 찾는 데 유용 할 수 있습니다. 게시물을 업데이트 할 수 있습니까? – Chizh

+0

올바른 WebApi 클라이언트 어셈블리를 사용하고 있지만 참조 오류가 발생했는지 확인하는 데 어려움을 겪고 있습니다. –

답변

4

내가 호출하는 어셈블리가 ASP.Net Core 릴리스에서 올바르게 작동하지 않는 것으로 확인되었습니다.

"Microsoft.AspNet.WebApi.Client": "5.2.3" 

내가이 라인에 그 라인을 변경했습니다 :

"System.Net.Http": "4.1.0" 

이 어셈블리가 동일한 API를 노출하지 않습니다 그래서 변경 한 위 project.json에서 보면 그것은이 라인 내 구현 코드 :

public async Task<IEnumerable<SkuGcn>> GetSkuGcnList() 
    { 
     HttpResponseMessage response = _client.GetAsync("/api/skuGcnList").Result; 

     if (response.IsSuccessStatusCode) 
     { 
      var skuGcns = await response.Content.ReadAsStringAsync() 
       .ContinueWith<IEnumerable<SkuGcn>>(getTask => 
       { 
        return JsonConvert.DeserializeObject<IEnumerable<SkuGcn>>(getTask.Result); 
       }); 
      return skuGcns; 
     } 

     return null; 
    } 

이 해결책은 효과적입니다.나는 포스트와 똑같은 문제가 있다는 것을 알아 두는 것이 중요하며 좀 더 복잡하기 때문에 나는 관심있는 사람을위한 포스트라는 또 다른 콜을 제공 할 것이다.

public async Task<IEnumerable<Availablity>> GetAvailabilityBySkuList(IEnumerable<string> skuList) 
    { 
     var output = JsonConvert.SerializeObject(skuList); 
     HttpContent contentPost = new StringContent(output, System.Text.Encoding.UTF8, "application/json"); 
     HttpResponseMessage response = _client.PostAsync("/api/availabilityBySkuList", contentPost).Result; 

     if (response.IsSuccessStatusCode) 
     { 
      var avail = await response.Content.ReadAsStringAsync() 
       .ContinueWith<IEnumerable<Availablity>>(postTask => 
       { 
        return JsonConvert.DeserializeObject<IEnumerable<Availablity>>(postTask.Result); 
       }); 
      return avail; 
     } 

     return null; 
    } 

감사합니다.

1

@DaniDev 동기 및 비동기 코드가 혼합 코멘트에서 언급 한 바와 같이 권장하지 않습니다. 이 주제에 대한 정식 기사는 Stephen Cleary의 Don't Block on Async Code입니다.

생성자에서 비동기 작업을 호출하고 constructors can't be async을 호출하기 때문에 코드 비동기를 작성하는 것이 약간 까다 롭습니다. 코드를 구조 조정

한 가지 방법은 (전화 비동기) 생성자 (의존성 주입)과 초기화를 분할하는 것입니다 코드 :

public class ProductItemsCacheStore 
{ 
    private readonly IItemsProductCacheRepository _itemsProductCacheRepo; 
    private readonly IProductAvailabilityPricing _productAvailabilityPricing; 
    private readonly IProductItemListRepo _productItemListRepo; 
    private readonly IItemsPricesCacheRepo _itemsPricesCacheRepo; 

    private bool _initialized = false; 

    public ProductItemsCacheStore(
     IItemsProductCacheRepository itemsRepo, 
     IProductAvailabilityPricing proxyGoliathApi, 
     IProductItemListRepo itemsListsRepo, 
     IItemPricesCacheRepo itemPricesRepo) 
    { 
     _itemsProductCacheRepo = itemsRepo; 
     _productAvailabilityPricing = proxyGoliathApi; 
     _productItemListRepo = itemsListsRepo; 
     _itemsPricesCacheRepo = itemsPricesRepo 
    } 

    public async Task Initialize() 
    { 
     // Could possibly move these to the constructor as well 
     var _items = itemsRepo.GetAllProductOrderListForCache(); 
     var _itemsLists = itemsListsRepo.GetItemListsForCache(); 
     var _priceZones = itemPricesRepo.GetAllPriceZonesAndItemPrices(); 

     MergeProductsWithGcn(_items, await _productAvailabilityPricing.GetSkuGcnList()); 

     _initialized = true; 
    } 
} 

귀하의 소모 코드 (당신이 어디에 있든 전에 new ProductItemsCacheStore(...)을 구축했다) 지금 물론

var productItemsCacheStore = new ProductItemsCacheStore(/* dependencies */); 
await productItemsCacheStore.Initialize(); 

이 당신의 소모 코드는 비동기로한다는 것을 의미한다 : 것 같습니다. 그것은 async all the way up입니다.

+0

나는 그것을 좋아하지만'Initialize()'를 호출한다. –

+0

@IrvLennert'ProductItemsCacheStore'을 소비하는 코드. 추가 답변을 코드 스 니펫으로 업데이트했습니다. –

+0

네, 네이트, 내가하고있는 일이 여기에있다. 1) 내가 작업을 반환 > (차단 없음) 줄에 2) 3) 4) 내가 할 대답이 필요합니다 1)에서 병합에 다음 줄에 5) 나는 나의 대답이있을 때까지 막고있다. 이것이 해석이 아니라면 저를 시정하십시오. 감사합니다 ... –