在Web Service(ASMX)中实现并发处理,控制服务性能

时间:2014-09-08 13:18:20

标签: c# .net parallel-processing task-parallel-library

这个问题是关于在Web Service(ASMX)中实现负载平衡。不是WCF。

我创建了Web服务(ASMX),我有一个WebMethod:

[WebMethod(Description = "Extracting data from the image.")]
public PersonData GetInfo(byte[] image)
{
     PersonData data = new PersonData();
     IFlexiCaptureProcessor processor = fcWebServiceProcessorsPool.GetProcessor();
     processor.AddImageFile(image);
     IDocument document = processor.RecognizeNextDocument();
     data.Number = document.Sections[0];
     data.Date = document.Sections[1];
     return data;
}

我的fcWebServiceProcessorsPool中有5个处理器 - 处理器数量取决于CPU核心数量。 我需要创建另一个WebMethod:

[WebMethod]
public List<PersonData> GetInfo(List<byte[]> images)
{
   //foreach byte[] image in images
   //...the same code
}

但我没有想法如何实现并发处理。 我的期望:

  • 1个请求= 100个图像; 5个处理器是免费的=&gt; 5个加载处理器 每张20张图片。
  • 一刻6个请求= 1个图像,1个图像,20个图像,30个图像,40个 图像,50张图像; 5个处理器是免费的=&gt; 5个加载处理器,1个请求 队列中。

1个任务是1个图像。 我的目标 - 始终同样加载每个处理器。

我该怎么做?这是我的第一个Web服务,所以我对它一无所知。我发现了很多关于ThrottlingBehavior的文章,但它引用了WCF,但我的程序不是WCF。我需要一些建议。

我使用我公司提供的.NET Framework 4.5和dll来处理图像。

1 个答案:

答案 0 :(得分:2)

为了平衡CPU /核心,您需要考虑什么?很多东西,例如:

  • Turbo Boost(或同等技术)。如果你有两个运行在3 GHz的核心和两个核心睡眠什么更好?唤醒另一个核心(将前两个磁盘放慢到2 GHz)或将任务排入这两个核心?
  • 缓存位置有什么好处?由于缓存(代码和/或数据),在同一个核心中排队类似任务会更有效吗?
  • 您对电力消耗有任何顾虑吗?
  • 所有内核均等负载?我的意思不仅仅是你的程序,而是系统和后台服务/流程。
  • 您是否考虑过基本的ASP.NET基础架构?你知道它在哪里运行吗?此外,不同的.NET / ASP.NET版本表现不同,并且技巧可能与另一个不兼容。

一般来说,从我的角度来看,这些细节实际上处于非常低的水平,而在ASP.NET中,您无法清楚地了解系统中发生的情况。即使您进行了认真的研究并且测量结果,您可能获得的是针对单个特定场景(以及单个特定CPU /系统架构)的有效内容。调整这些东西是件很难的事情,你需要详细信息(从运行时)和测试(从收集统计数据的大群体)。此外,即使您了解对于您的场景更好,您也无法控制所有这些事情(例如,您无法以编程方式唤醒核心)。

ASP.NET将在不同的线程中处理请求,您可以做的是并行执行计算。 .NET框架,底层操作系统以及最终CPU本身有更多细节可用于选择最佳方法,并且每个方案都将协同工作。

您正在使用C#编写ASP.NET,依靠经过严格测试和调整的组件会更容易(也更安全)。

在代码中(假设现代.NET即使.ASMX听起来很旧,如果你在.NET 2上运行,你只需要切换到直接在Parallel.ForEach上排队的手工ThreadPool实现)。请注意,这只是一个示例,用于描述我的意思,而不是您应该在生产中使用的代码:

[WebMethod]
public List<PersonData> GetInfo(List<byte[]> images)
{
    var result = new ConcurrentBag<PersonData>();

    Parallel.ForEach(images, image => {
        result.Add(GetInfo(image));
    });

    return result.ToList();
}

给出答案:不关心这些细节。使用可以使用的最高工具(库,语言和框架)编写并行,可伸缩和并发代码,并让底层知道平衡。