Alexey S. Larionov
Alexey S. Larionov

Reputation: 7947

Consume Stream from WCF as fast as possible

The setup:

App A runs a rendering of 3D models

App B generates models and sends them (plain text OBJ format) to App A via WCF's streaming operation

[OperationContract(IsOneWay = true)]
void VisualizeModel(Stream model);

I send models through localhost, so bandwidth should be big enough to send pretty huge models, but a rendering library I use has a slow method for reading them from a stream.

The problem

I need to prevent App B from waiting for a long time until App A consumes it completely (it takes up to 10 sec). So I try to copy the input stream into an intermediate stream

modelDrain = new MemoryStream(1024*1024*300);
model.CopyTo(modelDrain);
modelDrain.Position = 0;

then I start a Task to run rendering asynchronously, but I don't await for this Task - this way the WCF operation finishes practically as soon as I make the copy. It takes about 4 sec to finish the WCF operation this way. But the thing is that I generate these models in 2 sec, so I doubt that constructing the 3D model is twice as light than just copying it over HTTP.

The questions

Can I consume a WCF stream any other way (maybe via another Stream class) to speed the thing up?

Is HTTP over localhost that slow? (like 4 seconds to send about 100 Mb of text, while generating of such data takes only 2 seconds)

Upvotes: 0

Views: 128

Answers (1)

Ding Peng
Ding Peng

Reputation: 3974

In WCF, you can increase the transmission rate through compression encoder.The following will compare the effect of using compression encoder with that of not using compression encoder.

    public Stream Echo()
    {
        Bitmap bitmap = new Bitmap(1000, 40000);
        for (int i = 0; i < bitmap.Width; i++)
        {
            for (int j = 0; j < bitmap.Height; j++)
            {
                bitmap.SetPixel(i, j, (Math.Abs(i - j) < 2) ? Color.Blue : Color.Yellow);
            }
        }
        MemoryStream ms = new MemoryStream();
        bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);


        return ms;


    }

This is the stream to be transmitted.

     static void Main()
    {
        DateTime afterDT = System.DateTime.Now;
        Console.WriteLine(afterDT);
        SampleServerClient client = new SampleServerClient();
        client.Echo();
        afterDT = System.DateTime.Now;
        Console.WriteLine(afterDT);
        Console.WriteLine("OK");
        Console.ReadLine();
    }

This is the code of the client-side. I will record the time required for the client-side to receive the stream.

enter image description here

This is the time spent without using the compression encoder.

enter image description here

This is the time spent using compression encoder.

Due to the low efficiency of gzip image compression, the transmission performance has not been greatly improved, but if other large files, the performance will be improved a lot.

The following link is about how to use compression encoder in WCF:

https://learn.microsoft.com/en-us/dotnet/framework/wcf/samples/custom-message-encoder-compression-encoder

Upvotes: 1

Related Questions