2017-10-26 4 views
0

문제를 해결하는 방법을 알고 있는데 문제가 발생했습니다.API 호출을 비동기 적으로 수행

많은 제품이있는 웹 사이트가 있고이 페이지를 제품으로 채우기 위해 GetProducts이라는 API 공급자의 메소드를 호출합니다. 이것은 잘 작동하지만이 요청을 작은 요청으로 분할하여 비동기 적으로 실행하여이 프로세스를 가속화하고 싶습니다. GetProducts 메서드는 pageNumber 매개 변수를 제공합니다.이 매개 변수는 레코드의 다른 페이지를 가져 오도록 할 수 있습니다.

그래서이 문제를 해결하기 위해 여러 가지 방법을 시도했지만 어디에도 없습니다. 코드 예제 :

int n = 0; 
var tasks = new List<Task>(); 

// this method gets the total amount of products for the category 
totalAmountOfProducts = MyApi.GetProductsCount(category); 

while (n < totalAmountOfProducts/200) 
{ 
    for (int i = 0; i < 10; i++) 
    { 
     tasks.Add(GetProductsAsync(category, i, 200)); 
    } 

    n += i; 
    Task t = Task.WhenAll(tasks.ToArray()); 
    var totalProducts = // add products from the last 10 iterations to total in some way 
} 

private async Task<ProductList> GetProductsAsync(string category, int pageNumber, int productAmount) 
{ 
    return await Task.Run(() => MyApi.GetProducts(category, pageNumber, productAmount)) 
} 

어떻게해야합니까? 나는 세 가지 다른 버전을 시도했지만 그들은 모두 오류 또는 아무것도 안하고 결국 ... 아무것도. 그러나 이것이 완전히 잘못되었다는 것을 알고 있습니다 ... 예를 들어 awaitGetProductsAsync 방법으로 실행하고 있습니다. 정확하게 이해한다면 Task t = Task.WhenAll(tasks.ToArray()) 라인의 목적을 망칠 수 있습니다. 그러나 모든 것을 제거하는 유일한 방법이었습니다. ProductList 유형을 System.Action으로 변환 할 수 없다는 오류 메시지가 표시됩니다.

+0

'GetProductsAsync (category, i, 200)'결과로 아무 것도하지 않는 것 같습니다. – Igor

+2

'Parallel.ForEach'에 대한 작업과 같으며, 선택적으로 커스텀 파티셔너가 있습니다. 'async'는 (주로) 병렬 처리가 아닌 비동기를위한 것이며, 작동 시키더라도 비동기식 오버랩 (async-over-sync) 래퍼로 아주 좋은 시간을 갖지 못합니다. –

+0

@Fildor 죄송합니다. 코드를 복사 할 때 잘못 작성되었습니다. 고쳤다. @Jeroen Mostert 음 ... 나는 그들이 똑같은 생각이라고 생각하고 있었습니까? 확실히 Parallel.ForEach를 살펴볼 것입니다! – daveudou88

답변

2

당신은 Task.WhenAll의 앞에 기다리고 키워드를 넣어해야합니다 : 당신이 작업을 기다리고하지 않으면

var result = await Task.WhenAll(tasks.ToArray()); 

은, 코드 =이 .. 작업이 완료되지 않은 동기 할당 문 var에 totalProducts를 실행합니다 , 결과가 없거나 예외가 발생합니다.

+0

코드가 표시되지 않으므로 * 해당 코드가 수행 할 작업을 알 수 없습니다. 어쩌면 동기식으로 기다릴 수도 있고, 결과를 비동기식으로 가져올 수도 있으며, 작업이 완료되지 않았기 때문에 잘못된 결과를 얻을 수도 있습니다. 코드를 보지 않고 말할 수있는 방법이 없습니다. – Servy

관련 문제