2017-09-19 13 views
-1

나는 사용자가 많은 장기 실행 작업을 할 수있는 작업을 제출할 수있는 웹 응용 프로그램을 보유하고 있습니다. 웹 응용 프로그램이 진행률 표시 줄을 표시 할 수 있도록 yield return을 사용하고 있지만 동기 실행이 적용됩니다.수익률이 병렬로

내가하고 싶은 일은 내 작업 목록을 가져 와서 병렬로 실행하지만 여전히 사용자에게 피드백을 제공하는 것입니다.

아래 코드에서 Infer를 호출 할 때마다 return을 반환하지만 루프를 병렬로 실행하고 싶습니다. 이것이 수익률로 가능하지 않다면 내 옵션은 무엇입니까?

좀 더 구체적으로 말해서, 내가 원하는 것은 작은 요청으로 요청을 나누고 그 작은 목록을 병렬로 실행시키는 것입니다.

질문의 목적에 따라 '요청'을 'requests1'과 'requests2'로 나눠서 병렬로 실행하지만 각 항목이 완료된 후에도 호출자에게 되돌릴 수 있다고 가정 해 보겠습니다.

public IEnumerable<AnnotationRequest> Infer(List<Uri> fileUris, CancellationToken? token) 
    { 
     var requests = fileUris.Select(uri => new AnnotationRequest() { Uri = uri }).ToList(); 

     foreach (var result in Infer(requests, token)) 
     { 
      yield return result; 
     } 
    } 
+2

매우 광범위하게 보입니다. 사람이 접근 할 수있는 여러 가지 방법이 많이 있습니다. 각 그룹에 대해 별도의 작업을 시작하고 각 결과를 위의 기본 메소드/스레드에서'GetConsumingEnumerable()'을 통해 열거 한'BlockingCollection()'에 추가하는 작업을 시도 했습니까? –

답변

1

위의 Peter Duniho 주석 덕분에 나는 그의 제안과 그 잘 작동하는대로 구현했습니다.

  var collection = new BlockingCollection<AnnotationRequest>(); 

      Task.Run(() => 
      { 
       Parallel.ForEach(requests, (request) => 
       { 
        foreach (var result in Infer(request, token)) 
        { 
         collection.Add(result); 
        } 
       }); 

       collection.CompleteAdding(); 
      }); 

      foreach (var result in collection.GetConsumingEnumerable()) 
      { 
       yield return result; 
      }