2011-11-20 134 views
0

我有一個工作的Web服務,它在加載聯繫不同的網站,並從他們的相關信息。隨着需求的增長,httpwebrequests的數量也增加了。Web服務中的多個線程

現在我沒有在Web服務中使用任何異步請求 - 這意味着ASP.net一次呈現一個請求。這顯然成爲一個負擔,因爲對web服務本身的一個請求可能需要2分鐘才能完成。

有沒有辦法將webservice中的所有這些httpwebreqeusts轉換爲多線程?

什麼是最好的方法來實現這一目標?

謝謝!

回答

0

如果您使用的是.Net V4 +,則可以使用並行庫或任務庫,它們可以輕鬆完成這些任務。

如果使用同樣的方式調用您的所有Web服務(假設所有Web服務方面是相同的WSDL,只是不同的網址,就可以使用這樣的事情):

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); 
     } 
    } 
} 

這個小程序首先下載html頁面,然後提取所有的href。這會產生一組遠程文件。這裏的AsParralel允許以並行的方式運行select的內容。

此代碼沒有錯誤處理,取消功能但說明了AsParallel方法。

如果您不能調用以同樣的方式你所有的web服務,您也可以使用這樣的事情:

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

該代碼將新增4項任務,將運行「如果可能」。 WaitAll方法將在返回之前等待所有任務完成。

儘可能我的意思是當線程池中的一個插槽是空閒的。使用任務庫時,每個處理器內核默認有一個線程池。如果您有100個任務,則100個任務將由4個核心計算機上的4個工作線程處理。