2017-03-04 6 views
0

에서 첫 번째 Http 응답 받기 나는 5 개의 URL을 가지고 있으며 각 요청에 대해 HTTP 요청을 만들고 싶다. 그리고 조건이있는 첫 번째 응답을 기다리고있다.Parallel

List<string> urls; // url1, url2, ...... 

ParallelLoopResult result = Parallel.ForEach(urls, url=> GetTimeSlot(url)); 

private string GetTimeSlot(string url) 
{ 
    HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url); 

    HttpWebResponse response = (HttpWebResponse)wr.GetResponse(); 
     string responseString = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(response.CharacterSet)).ReadToEnd(); 
     if (responseString.Length < 6) 
      return ""; //PARALEL RESUME 
     else 
      return responseString; //PARALEL ENDS 
} 

나는 첫 번째 응답이 필요합니다. 병렬 처리가 가능합니까 아니면 더 좋은 방법이 있습니까? 감사.

답변

2

Parallel.ForEach는 사용 사례에 특히 유용합니다. 취소 토큰을 사용하여 다른 모든 실행중인 작업을 중지하십시오.

static void Main(string[] args) 
    { 
     var cts = new CancellationTokenSource(); 
     var _lock = new Object(); 
     var po = new ParallelOptions(); 
     po.CancellationToken = cts.Token; 
     po.MaxDegreeOfParallelism = System.Environment.ProcessorCount; 
     var listOfUrls = new List<string>() { "url1", "url2" }; 
     var responsResult = ""; 
     try 
     { 
      Parallel.ForEach(listOfUrls, po, (url) => 
      { 
       po.CancellationToken.ThrowIfCancellationRequested(); 

       HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url); 

       HttpWebResponse response = (HttpWebResponse)wr.GetResponse(); 
       string responseString = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(response.CharacterSet)).ReadToEnd(); 

       lock (_lock) 
       { 
        if (responseString.Length > 6) 
        { 
         responsResult = responseString; 
         cts.Cancel(); 
        }       
       }   

      }); 
     } 
     catch (OperationCanceledException e) 
     { 
      //cancellation was requested 
     } 
     finally 
     { 
      cts.Dispose(); 
     } 
    } 
+0

는 확실히 다른 스레드가 결과를 업데이트하지 않습니다 있도록 잠금을 사용합니다. Throw 된 OperationCanceledException은 cts.Cancel();을 호출 할 때 기대하는 것입니다. 다른 예외이지만 OperationCanceledException 인 경우 WebRequest에 문제가 있음을 의미합니다. – Dynamikus

+0

고맙습니다. 그것은 일했다!! 나는'자물쇠 '를 시험 할 것이다. –

+0

np 행운을 빕니다 !!! – Dynamikus

1

당신은 PLINQ를 사용할 수 있습니다

string firstResponse = urls 
    .AsParallel() 
    .Select(url => GetTimeSlot(url)) 
    .FirstOrDefault(r => ! string.IsNullOrEmpty(r))     
    ; 
+0

감사합니다. @ 헹크. 그것은 첫 번째 응답을 얻을 때 작업을 취소합니까? –

+0

아무 것도 취소하지 않지만 새로 시작하지 않습니다. 이미 실행중인 모든 작업이 완료됩니다. 헛된. –