2011-11-20 67 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个工作线程处理。