我使用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" %>
我相信每个客户端的web metod调用都是创建新实例的 MatlabService和WCF服务工作是在新线程(WCF服务)上进行的 线程)和OS将此线程分配给CPU核心。
或者我错了,行为每次调用都要创建新的服务对象 在ServiceBehavior属性中定义InstanceContextMode? p>
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
在web方法中我使用的MatlabService计算 System.Threading.Tasks用于并行化,所以数学工作就是这样做的 另一个线程(数学线程)。
为每个调用创建WCF服务线程并在WCF服务中创建 线程是创建数学线程。
我不确定这是否属实。
可能需要在WCF服务中允许多线程 ConcurrencyMode? P>
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall,ConcurrencyMode = ConcurrencyMode.Multiple)]
我想听听如何为多核CPU并行化web metod调用的想法。 我谷歌它,但没有找到任何明确和有用的因为我使用Spring.NET框架创建WCF服务。
答案 0 :(得分:1)
默认的实例上下文模式是PerCall,因此显式设置是多余的。
是的,你正在创建一个额外的线程来进行数学运算,但是你没有获得任何东西,因为你在任务完成之前就阻塞了。实际上,它的效率较低,因为您需要创建和管理其他线程的开销。
每个网络电话都已在其自己的主题中提供服务。
我唯一可以看到添加额外并行计算的地方是:
MatlabManager.CalculateWithFiniteElementMethod(data)
然而,这看起来像是对Matlab的调用。如果您可以使用并行代码重新实现该方法,则可能会获得一些性能提升。
无论你做什么,分析都是理解你是否真正加快速度的关键。记住 - 并行并不总是意味着更快。同步这些操作并为它们创建线程会有开销。