使用WCF流的高CPU负载

时间:2014-02-04 06:43:10

标签: c# wcf stream cpu-usage

我一直在对这个问题进行大量研究,但不幸的是我无法找到解决方案。 我的问题是,即使在使用WCF(NetTcpBinding,Streamed)的强大机器上,我也遇到了相当高的CPU负载 - 更具体地说,我的i5 860在处理20个客户端线程时负载为20-40%。在部署真实服务(而不是测试项目)时,大约有50个真实客户端每秒发送一次小数据包(每次传输大约20kb),CPU负载已经达到80-90%。最终应该有200多个客户端,但我无法想象这应该如何适用于这样的CPU负载......

出于测试目的,我已经使用NetTcpBinding建立了一个基于WCF流传输的简单客户端和服务器的小项目。其中已经有很多“绝望代码”,因为我试图让它工作......对于我的测试,我使用了一个200MB的文件,该文件被发送到WCF服务20次。

这是合同:

[ServiceContract(Namespace = "WCFStreamTest.WCFService")]
public interface IStreamContract
{
    [OperationContract(Name = "ReceiveStream")]
    StreamMessage ReceiveStream(StreamMessage msg);

    [OperationContract(Name = "SendStream")]
    StreamMessage SendStream(StreamMessage msg);
}

这里使用的StreamMessage类只是一个包含字符串头和Stream对象的MessageContract。

服务器代码如下所示:

[ServiceBehavior(IncludeExceptionDetailInFaults = false, InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext = true, MaxItemsInObjectGraph = int.MaxValue)]
public class StreamService : IStreamContract
{
    public StreamMessage ReceiveStream(StreamMessage msg)
    {
        if (File.Exists(msg.Parameters))
            return new StreamMessage() { Parameters = msg.Parameters, DataStream = new System.IO.FileStream(msg.Parameters, System.IO.FileMode.Open, System.IO.FileAccess.Read) };

        return new StreamMessage();
    }

    public StreamMessage SendStream(StreamMessage msg)
    {
        if (msg.Parameters.Trim().Length > 0)
        {
            int bufferSize = 8096 * 4;
            byte[] buffer = new byte[bufferSize];
            int bytes = 0;

            while ((bytes = msg.DataStream.Read(buffer, 0, bufferSize)) > 0)
            {
                byte b = buffer[0];
                b = (byte)(b + 1);
            }
        }

        return new StreamMessage();
    }
}

测试项目只使用SendStream方法进行测试 - 该方法只读取数据流而不执行任何操作。

此时我想我只是节省你的阅读时间,不要在这里发布完整的代码。也许一个演示项目的下载链接就足够了? (为了使其工作,客户端的Program.cs中有一行要更改的对象:FileInfo fi = new FileInfo(@“<<<>>>”);)

WCFStreamTest Project

我对如何降低CPU使用率的想法感到非常高兴...在此先感谢任何帮助和提示......

1 个答案:

答案 0 :(得分:0)

你可以尝试让线程在循环中进入睡眠状态,看看它是如何进行的。

while ((bytes = msg.DataStream.Read(buffer, 0, bufferSize)) > 0)
{
    byte b = buffer[0];
    b = (byte)(b + 1);
    Thread.Sleep(100);
}

如果是视频流服务,您可能需要调整睡眠间隔。