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(@"<<<>>>");)
I'd be really happy about any idea on how to lower CPU usage... thanks in advance for any help and tips...