5

Webtesting 도구의 URL 목록을 기반으로 HTML 페이지 소스를 검색해야하는 .NET 4 도우미/유틸리티 클래스를 구현하려고합니다. 솔루션은 확장 가능하고 고성능이어야합니다.비동기 웹 요청을 사용하여 멀티 스레딩을 수행하는 방법

저는 이미 여러 가지 해결책을 연구하고 시도해 왔지만 적절한 해결책을 찾을 수 없습니다.

나의 목표를 달성하는 가장 좋은 방법은 TPL을 사용하여 병렬로 실행되는 비동기 webrequests를 사용하는 것입니다.

헤더 등을 완벽하게 제어하기 위해 HttpWebResponse를 래핑하는 WebClient 대신 HttpWebResponse를 사용하고 있습니다. 경우에 따라 출력을 다른 작업에 연결해야하므로 TPL 작업을 사용하는 것이 타당 할 수 있습니다. 나는 많은 다른 시험/접근 한 후 지금까지 달성 한 무엇

,

  1. 다른 솔루션의 성능 수준을보고 솔루션 (TPL 작업을 사용하여) 기본 동기, 비동기 (APM)과 평행하게 구현됩니다.

  2. 비동기 병렬 솔루션의 성능을 보려면 APM 방식 인 BeginGetResponse 및 BeginRead를 사용하여 Parallel.ForEach에서 실행하십시오. 모든 것이 잘 작동하고 성능에 만족합니다. 어떻게 든 나는 간단한 Parallel.ForEach를 사용하는 것이 갈 길이 아니라고 생각하고 예를 들어 내가 어떻게 작업 체인을 사용하는지 모르겠습니다.

  3. 그런 다음 TaskCompletionSource 및 반복기를 사용하여 APM 흐름을 반복하여 APM 솔루션을 래핑하는 작업을 사용하여보다 정교한 시스템을 시도했습니다. 나는이 솔루션이 내가 원하는 것일 수 있다고 생각하지만 이상한 지연이있다. 6-10 초 사이에 500 회의 URL 목록을 실행할 때 2-3 번 발생한다.

    로그를 기반으로 지연이 발생할 때 루프에서 async fetch를 호출하는 스레드로 실행이 되돌아갔습니다. 지연은 실행이 루프로 돌아갈 때 항상 발생하지는 않습니다. 단지 2-3 번이고 다른 시간에는 정상적으로 작동합니다. 반복 스레드가 다른 스레드에서 처리되는 작업 집합을 생성하고 루프가 나머지 작업을 생성하고 다른 스레드가 다시 활성화되기 전에 대부분/모든 작업이 완료되면 지연 (6-8 초)이 발생하는 것처럼 보입니다. .

루프 내부 반복자의 원리는 다음과 같습니다

IEnumerable<Task> DoExample(string input) 
    { 
    var aResult = DoAAsync(input); 
    yield return aResult; 
    var bResult = DoBAsync(aResult.Result); 
    yield return bResult; 
    var cResult = DoCAsync(bResult.Result); 
    yield return cResult; 
    … 
    } 

Task t = Iterate(DoExample(“42”)); 

내가

내 질문 ThreadPool.RegisterWaitForSingleObject

사용 System.Net.ServicePointManager.DefaultConnectionLimit 및 시간 제한을 사용하여 연결 제한을 해결 해요 간단히 말해, html 페이지를 검색하기위한 헬퍼/유틸리티 클래스를 구현하는 가장 좋은 방법은 무엇입니까?

  • 는 확장 성 및 고성능을
  • 가 타임 아웃을
  • 사용을 사용할 수
  • 쉽게 다른 작업에 체인
  • 사용 webrequests 있습니다.NET 4 framework

위에서 제시 한 APM, TaskCompletionSource 및 iterator를 사용하는 솔루션이 좋다고 생각하면 지연 문제를 해결하기위한 모든 도움에 감사드립니다.

저는 C# 및 Windows 개발에 완전히 익숙해졌습니다. 그래서 제가 시험해보고있는 것이 너무 많은 의미를 갖지 않는다면 제발 신경 쓰지 마십시오.

아무 도움도없이이 문제가 해결되지 않으면 테스트 도구 개발을 중단해야합니다. 반복자를 사용

감사

+0

반복자를 어떻게 사용하고 있으며 실제로 반복자로 사용하는 것이 유용하다고 생각하는지 자세히 설명해 주시겠습니까? – svick

+0

다양한 솔루션을 시도한 후에 msdn 블로그의 MS 전문가 조언을 기반으로 반복기를 사용하여 종료했습니다. 내 솔루션은 블로그에서와 거의 같거나 시간 초과 및 로깅을 추가했습니다. 반복기를 사용할 구체적인 이유가 없으며 작동하는 모든 솔루션에 개방적입니다. 코드 스 니펫에 대한 링크 : http://social.msdn.microsoft.com/Forums/en-US/parallelextensions/thread/95355648-1fa6-4b2d-a260-954c3421c453/ – Laowai

답변

0

가 사전 TPL .NET에서 훌륭한 솔루션이었다 (예를 들어, MS 로보틱스 밖으로 조정 및 동시성 런타임 (CCR)은 그 중 많이 사용했고 TPL 영감을 도움). 한 가지 문제는 반복자만으로는 필요한 것을 제공하지 않는다는 것입니다. 작업 부하를 효과적으로 분산 시키려면 스케줄러가 필요합니다. 즉, 연결 스티븐 Toub의 조각에 의해 수행 거의 -하지만 한 줄 참고 :

enumerator.Current.ContinueWith(recursiveBody, TaskContinuationOptions.ExecuteSynchronously); 

난 당신이 "ExecuteSynchronously을"강제로 연결 될 수 있습니다 볼 수있는 간헐적 인 문제를 생각한다 - 그것이 원인이 될 수 사용 가능한 코어/스레드에서 작업의 고르지 않은 분산.

스티븐이 제안한 다른 대안 중 하나를 살펴보십시오. in his blog article. 특히, ContinueWith() 호출의 간단한 연결을 수행하는 것이 무엇인지 살펴보십시오 (필요한 경우 Unwrap() 호출과 일치 함). 구문이 가장 좋지는 않지만 가장 단순하고 근본적인 작업 도용 런타임과 가능한 한 간섭하지 않으므로 더 나은 결과를 얻을 수 있습니다.

+0

제안 및 의견을 보내 주셔서 감사합니다. 스티븐의 블로그를 자세히 살펴볼 것입니다. – Laowai

+0

예! 우리가 찾은 것을 알려주십시오. –

관련 문제