1

我使用 Spring.NET 框架创建 WCF 服务。该服务是数学服务,为客户端应用程序提供一些计算。

我对多核服务器上的 WCF 服务并行化有疑问。举个简单的例子,我有 20 个内核的服务器。

首先是一个简化的代码。

//WS interface
public interface IMatlabService
{
    List<ResultData> Calculate(byte [] data);
}

//WS class definition
[ServiceBehavior(Namespace = "http://server.com/MatlabService")]
public class MatlabService: IMatlabService
{
    public IMatlabManager MatlabManager{get;set:}

    //web metod for math computations
    public List<ResultData> Calculate(byte [] data)
    {
        var result = new List<ResultData>();

        //do math work in another thread
        Task<List<ResultData>> task = Task.Factory.StartNew<List<ResultData>>(() =>
                                                           {
                                                               return MatlabManager.CalculateWithFiniteElementMethod(data);
                                                           });

        result.AddRange(task.Result)

        return result;

    }
}

public interface IMatlabManager 
{
    List<ResultData> CalculateWithFiniteElementMethod(byte [] data);
}

public class MatlabManager : IMatlabManager 
{
    public List<ResultData> CalculateWithFiniteElementMethod(byte [] data)
    {
        // do some math work
    }
}

使用 Spring.NET,我将 Web 服务和管理器类配置为非单例。

Spring.NET XML 配置在这里。

Matlab 管理器配置:

  <object name="matlabManager"
          type="MatlabManager"
          singleton="false"/>

MatlabService 配置:

  <object name="matlabService"
          type="MatlabService"
          singleton="false">
       <property name="MatlabManager" ref="matlabManager"/>
  </object>

来自 web.config 的 WCF 服务配置

 <behavior name="Behavior1">
     <serviceMetadata httpGetEnabled="true"/>
     <serviceDebug includeExceptionDetailInFaults="true"/>
  </behavior>

<services>
  <service name="matlabService" 
            behaviorConfiguration="Behavior1">
    <endpoint address="" 
            binding="basicHttpBinding" 
            contract="IMatlabService" 
            bindingNamespace="http://server.com/MatlabService"/>
    <endpoint contract="IMetadataExchange" 
            binding="mexHttpBinding" 
            address="mex"/>
  </service>
</services>

SVC 文件。

<%@ ServiceHost Language="C#" Debug="true" Service="MatlabServiceService" Factory="Spring.ServiceModel.Activation.ServiceHostFactory" %>
  1. 我相信对于每个客户端 Web 方法调用都会创建 MatlabService 的新实例,并且 WCF 服务工作是在新线程(WCF 服务线程)上完成的,并且操作系统将此线程分配给 CPU 核心。

    或者我错了,行为每次调用都会创建新的服务对象,我必须在 ServiceBehavior 属性 InstanceContextMode 中定义?

    [服务行为(InstanceContextMode=InstanceContextMode.PerCall)]

  2. 在 MatlabService 的 Web 方法计算中,我使用 System.Threading.Tasks 进行并行化,因此数学工作在另一个线程(数学线程)中完成。

    为每个调用创建 WCF 服务线程,并在 WCF 服务线程中创建数学线程。

    我不确定这是否属实。

    也许需要在 ConcurrencyMode 中允许 WCF 服务中的多线程?

    [ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall,ConcurrencyMode = ConcurrencyMode.Multiple)]

我想听听如何并行化多核 CPU 的 web 方法调用。我用谷歌搜索,但没有找到任何清晰有用的东西,因为我使用 Spring.NET 框架来创建 WCF 服务。

4

1 回答 1

1
  1. 默认实例上下文模式是 PerCall,因此显式设置是多余的。

  2. 是的,您正在创建一个额外的线程来执行数学运算,但是您没有获得任何东西,因为您在任务完成之前一直处于阻塞状态。事实上,它的效率较低,因为您有创建和管理额外线程的开销。

每个 Web 调用都已在其自己的线程中提供服务。

我可以看到添加额外并行计算的唯一地方是在以下实现中:

MatlabManager.CalculateWithFiniteElementMethod(data)

但是,这看起来像是对 Matlab 的调用。如果您可以使用并行代码重新实现该方法,您可能会获得一些性能提升。

无论您做什么,分析都是了解您是否真的在加快速度的关键。请记住 - 并行并不总是意味着更快。同步这些操作并为它们创建线程是有开销的。

于 2012-09-07T20:16:17.447 回答