0

Currently my app returns data by MemoryStream, the problem is the size of data could be large than 500MB, and that takes up much memory before return.

I am seeking for a way to return the data progressively. For example, flush the output for every 1MB.

First I tried IPartialWriter

public class ViewRenderResult : IPartialWriter
{
    public void WritePartialTo(IResponse response)
    {
        response.Write("XXX");

    }

    public bool IsPartialRequest { get { return true; } }
}

response.Write can only be called for one time.

Then I found IStreamWriter

public interface IStreamWriter
{
    void WriteTo(Stream responseStream);
}

I doubt it caches all data before returining.

Please can anyone clarify it?

Mr.Wang from Next Door
  • 13,670
  • 12
  • 64
  • 97

1 Answers1

2

This previous answer shows different response types ServiceStack supports, e.g. you can just return a Stream or write to the base.Response.OutputStream directly from within your Service.

These ImageServices also shows the different ways you can write a binary response like an Image to the response stream, e.g. here's an example of using a custom IStreamWriter which lets you control how to write to the Response OutputStream:

//Your own Custom Result, writes directly to response stream
public class ImageResult : IDisposable, IStreamWriter, IHasOptions
{
    private readonly Image image;
    private readonly ImageFormat imgFormat;

    public ImageResult(Image image, ImageFormat imgFormat = null)
    {
        this.image = image;
        this.imgFormat = imgFormat ?? ImageFormat.Png;
        this.Options = new Dictionary<string, string> {
            { HttpHeaders.ContentType, this.imgFormat.ToImageMimeType() }
        };
    }

    public void WriteTo(Stream responseStream)
    {
        using (var ms = new MemoryStream())
        {
            image.Save(ms, imgFormat);
            ms.WriteTo(responseStream);
        } 
    }

    public void Dispose()
    {
        this.image.Dispose();
    }

    public IDictionary<string, string> Options { get; set; }
}

Which you can return in your Service with:

public object Any(ImageAsCustomResult request)
{
    var image = new Bitmap(100, 100);
    using (var g = Graphics.FromImage(image))
    {
        g.Clear(request.Format.ToImageColor());

        return new ImageResult(image, request.Format.ToImageFormat()); 
    }
}
Community
  • 1
  • 1
mythz
  • 141,670
  • 29
  • 246
  • 390