2011-11-20 2 views
0

로드 중 On으로 다른 웹 사이트에 접속하여 관련 정보를 스크랩하는 작업 웹 서비스가 있습니다. 요구 사항이 증가함에 따라 httpwebrequests도 증가했습니다.웹 서비스의 여러 스레드

지금 웹 서비스에서 비동기 요청을 사용하지 않습니다. 즉, ASP.net은 한 번에 하나의 요청을 렌더링합니다. 이는 웹 서비스 자체에 대한 하나의 요청이 완료되는 데 최대 2 분이 소요될 수 있으므로 분명히 부담이되었습니다.

웹 서비스 내부의 모든 httpwebreqeusts를 멀티 스레드로 변환 할 수있는 방법이 있습니까?

이것을 달성하는 가장 좋은 방법은 무엇입니까?

감사합니다.

답변

0

.Net V4 +로 작업하는 경우, 이러한 작업을 쉽게 수행 할 수있는 병렬 라이브러리 또는 태스크 라이브러리를 사용할 수 있습니다.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Net; 
using System.Text.RegularExpressions; 

namespace ConsoleApplication2 
{ 
    class Program 
    { 
     private const string StartUrl = @"http://blog.hand-net.com"; 

     private static void Main() 
     { 
      var content = DownloadAsString(StartUrl); 

      // The "AsParallel" here is the key 
      var result = ExtractUrls(content).AsParallel().Select(
       link => 
       { 
        Console.WriteLine("... Fetching {0} started", link); 
        var req = WebRequest.CreateDefault(new Uri(link)); 

        var resp = req.GetResponse(); 

        var info = new { Link = link, Size = resp.ContentLength}; 

        resp.Close(); 

        return info; 
       } 
       ); 

      foreach (var linkInfo in result) 
      { 

       Console.WriteLine("Link : {0}", linkInfo.Link); 
       Console.WriteLine("Size : {0}", linkInfo.Size); 
      } 
     } 

     private static string DownloadAsString(string url) 
     { 
      using (var wc = new WebClient()) 
      { 
       return wc.DownloadString(url); 
      } 
     } 

     private static IEnumerable<string> ExtractUrls(string content) 
     { 
      var regEx = new Regex(@"<a\s+href=""(?<url>.*?)"""); 
      var matches = regEx.Matches(content); 

      return matches.Cast<Match>().Select(m => m.Groups["url"].Value); 
     } 
    } 
} 

이 작은 프로그램은 먼저 다운로드 : 동일한 방법을 사용하여 모든 웹 서비스를 호출 할 경우

은 (단지 다른 URL을 같은 WSDL을 모든 웹 서비스를 존중 가정, 다음과 같이 사용할 수 있습니다) html 페이지에서 href를 모두 추출하십시오. 이렇게하면 원격 파일 배열이 생성됩니다. 여기에서 AsParralel은 select의 내용을 병렬 방식으로 실행할 수 있습니다.

이 코드에는 오류 처리, 취소 기능이 없지만 AsParallel 메서드가 나와 있습니다. 이 코드는 4 개 작업을 추가합니다

 Task.WaitAll(
      Task.Factory.StartNew(()=>GetDataFromWebServiceA()), 
      Task.Factory.StartNew(()=>GetDataFromWebServiceB()), 
      Task.Factory.StartNew(()=>GetDataFromWebServiceC()), 
      Task.Factory.StartNew(()=>GetDataFromWebServiceD()), 
      ); 

, "가능하다면"실행됩니다 : 당신은 같은 방법으로 모든 웹 서비스를 호출 할 수 없습니다 경우

, 당신은 또한이 같은 것을 사용할 수 있습니다. WaitAll 메서드는 반환 전에 모든 작업이 완료 될 때까지 대기합니다.

가능할 때마다 스레드 풀의 슬롯이 비어있을 때를 의미합니다. 태스크 라이브러리를 사용할 때, 기본적으로 프로세서 코어마다 하나의 스레드 풀이 있습니다. 100 개의 작업이있는 경우 100 개의 작업 공간은 4 코어 컴퓨터에서 4 개의 작업자 스레드로 처리됩니다.