0
votes

I've been doing a lot of research on this issue but unfortunately I wasn't able to find a solution. My problem is that I am experiencing a quite high CPU load even on powerful machines when using WCF (NetTcpBinding, Streamed) - to be more specific, my i5 860 has a load of 20-40 percent when handling 20 client threads. When it comes to deploying a real service (and not a testing project) and there's around 50 real clients sending small data packages every second (around 20kb per transfer) the CPU load is already at 80-90 percent. In the end there should be 200+ clients but I can't imagine how this should work with such CPU loads...

For testing purposes I have set up a small project with just a simple client and server based on WCF streamed transfer using NetTcpBinding. There's already a lot of 'desperation code' in it, because I have tried to make it work... for my testing I used a 200MB file that's being sent to the WCF service 20 times.

Here's the contract:

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

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

The StreamMessage class used in here is just a MessageContract containing a string header and a Stream object.

The server code looks as follows:

[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();
    }
}

The test project just uses the SendStream method for testing - and that method just reads the data stream and does nothing else.

At this point I think I'll just save your time reading and don't post the full code in here. Maybe a download link to the demo project will be sufficient? (To make it work there is one line in the client's Program.cs that's object to be changed: FileInfo fi = new FileInfo(@"<<<>>>");)

WCFStreamTest Project

I'd be really happy about any idea on how to lower CPU usage... thanks in advance for any help and tips...

1
Hi, how you managed to resolve your issue, also experiencing the same thing?Donald N. Mafa

1 Answers

0
votes

Can you try to make the thread sleep in while loop, and see how it goes.

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

If it is a video streaming service you might have to tweak the sleep interval.