当使用WCF调用Cisco的AXL SOAP API时,CPU占用率过高。我从使用wsdl生成的类创建服务模型客户端开始。我使用basichttpbinding和transfermode作为缓冲。执行呼叫时,CPU会最大化,而CPU配置文件显示,在调用(如base.Channel.getPhone(request);
)之后调用的clr.dll中,96%的CPU时间为[email protected]
。更正确地说,这个调用最大化了进程正在运行的CPU核心。在调用期间等待_TransparantProxyStub_CrossContext函数时,WCF maxes CPU
下面是从WSDL客户创造剪断产生
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public partial class AXLPortClient : System.ServiceModel.ClientBase<AxlNetClient.AXLPort>, AxlNetClient.AXLPort
{
public AXLPortClient()
{
}
public AXLPortClient(string endpointConfigurationName) :
base(endpointConfigurationName)
{
}
...
这是我如何创建客户端:
public class AxlClientFactory : IAxlClientFactory
{
private const string AxlEndpointUrlFormat = "https://{0}:8443/axl/";
public AXLPortClient CreateClient(IUcClientSettings settings)
{
ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true;
ServicePointManager.Expect100Continue = false;
var basicHttpBinding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
basicHttpBinding.MaxReceivedMessageSize = 20000000;
basicHttpBinding.MaxBufferSize = 20000000;
basicHttpBinding.MaxBufferPoolSize = 20000000;
basicHttpBinding.ReaderQuotas.MaxDepth = 32;
basicHttpBinding.ReaderQuotas.MaxArrayLength = 20000000;
basicHttpBinding.ReaderQuotas.MaxStringContentLength = 20000000;
basicHttpBinding.TransferMode = TransferMode.Buffered;
//basicHttpBinding.UseDefaultWebProxy = false;
var axlEndpointUrl = string.Format(AxlEndpointUrlFormat, settings.Server);
var endpointAddress = new EndpointAddress(axlEndpointUrl);
var axlClient = new AXLPortClient(basicHttpBinding, endpointAddress);
axlClient.ClientCredentials.UserName.UserName = settings.User;
axlClient.ClientCredentials.UserName.Password = settings.Password;
return axlClient;
}
}
为AXL API生成的WSDL代码是非常大的。尽管后续调用速度更快,但初始和后续调用都有CPU问题。还有什么我可以做的调试这个问题?有没有办法来减少这种高CPU使用率?与赏金
更新
多一点信息:
我创建了C#类,像这样:
svcutil AXLAPI.wsdl AXLEnums.xsd AXLSoap.xsd /t:code /l:C# /o:Client.cs /n:*,AxlNetClient
您必须下载思科的AXL API的WSDL从呼叫管理系统。我正在使用API的10.5版本。我认为主要的放缓与XML处理有关。 api的WSDL非常庞大,所产生的类会产生538406行代码!
更新2
我打开WCF与各级跟踪。最大的时间差异在“消息写入”和“通过通道发送消息”之间的过程操作活动中,在这两个操作之间几乎需要一整分钟。其他活动(构建通道,开放客户端和关闭客户端)都执行得相对较快。
更新3
我已经做了两个修改生成的客户端类。首先,我从所有运营合同中删除了ServiceKnownTypeAttribute
。其次,我从一些可序列化的类中删除了XmlIncludeAtribute。这两项更改将生成的客户端的文件大小减少了50%以上,并且对测试时间影响很小(70s测试结果减少了大约10s)。
我还注意到,对于单个服务接口和端点,我大约有900个操作合同。这是由于AXL API的wsdl将单个命名空间下的所有操作分组在一起。我正在考虑打破这种情况,但这意味着要创建多个客户端,每个客户端都会实现一个简化的界面,并最终打破实现这个wcf库的所有内容。
更新4
它看起来像操作的数量是核心问题。我能够用动词(例如,动词)分离出操作和界面定义。获取,添加等)到他们自己的客户端和接口中(使用崇高文本和正则表达式作为resharper和codemaid无法处理大型文件仍然是250K +行)的非常慢的过程。与定义了大约150个操作的“Get”客户端的测试相比,前60秒的结果导致getPhone执行10秒。这仍然比应该做得慢很多,就像在小提琴手的结果中简单地在2秒内执行这个操作一样。通过尝试进一步分离操作,该解决方案可能会进一步减少操作次数。但是,这增加了一个新的问题,即打破将这个库用作单个客户端的所有系统。
由于这不是一个确凿的回应,我会分享一个类似的经验。我创建了一个包含许多操作和大型wsdl的wcf。我有一个类似的问题,高CPU使用率。我解决了这个问题,在wcf项目上设置序列化程序集。在项目属性build部分中,您可以尝试将“生成序列化程序集”设置为“开”,并根据您的方式将“Xml文档”设置为文件夹“bin \ release”或“bin \ debug”构建您的解决方案让我知道如果工作,我可以写一个答案并发布更多有关此解决方法。 –
我没有从设置这两个选项增加性能。我在发布配置中运行单元测试,并将序列化设置为auto,根据此(https://stackoverflow.com/questions/9187248/when-to-change-the-generate-serialization-assembly- value)表示序列化已打开已经。 Xml文档是用于将注释翻译成intellisence afik,但我仍然尝试过。 –