【问题标题】:High CPU load using WCF streaming使用 WCF 流的高 CPU 负载
【发布时间】:2014-02-04 06:43:10
【问题描述】:

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

出于测试目的,我建立了一个小项目,其中只有一个简单的客户端和服务器,基于 WCF 流传输,使用 NetTcpBinding。里面已经有很多“绝望代码”,因为我试图让它工作......为了我的测试,我使用了一个 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类只是一个MessageContract,包含一个字符串头和一个Stream对象。

服务器代码如下:

[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 使用率的想法,我会非常高兴...在此先感谢您提供的任何帮助和提示...

【问题讨论】:

  • 您好,您的问题是如何解决的,也遇到了同样的问题?

标签: c# wcf stream cpu-usage


【解决方案1】:

你能不能尝试让线程在while循环中休眠,看看效果如何。

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

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

【讨论】:

  • 是的,我已经尝试过了。它会稍微降低服务器端的 CPU,但不会降低很多。我发现大部分 CPU 使用率来自发送部分:在这种情况下,是客户端打开流并将其发送到服务器,尽管服务器从流中读取,但会占用大量 CPU。服务器不仅接收流,而且向其他客户端发送流,这一事实使得它使用了如此多的 CPU。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-14
相关资源
最近更新 更多