Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using statement in Task

In an ASP.NET Web API controller I want to return an image. For streaming the image I need a MemoryStream. Normally I would wrap it in a using statement in order to make sure it gets properly disposed afterwards. However, as this executes asynchronously in a Task this doesn't work:

public class ImagesController : ApiController
{
    private HttpContent GetPngBitmap(Stream stream)
    {
        var pngBitmapEncoder = new PngBitmapEncoder();
        pngBitmapEncoder.Save(stream);
        stream.Seek(0, SeekOrigin.Begin);
        return new StreamContent(stream);
    }

    // GET api/images
    public Task<HttpResponseMessage> Get(string id, string path)
    {            
        //do stuff           
        return Task.Factory.StartNew(() =>
        {
            var stream = new MemoryStream(); //as it's asynchronous we can't use a using statement here!
            {
                var response = new HttpResponseMessage(HttpStatusCode.OK)
                {
                    Content = GetPngBitmap(stream)
                };
                response.Content.Headers.ContentType =
                    new System.Net.Http.Headers.MediaTypeHeaderValue("image/png");
                return response;
            }
            //how can I dispose stream???
        });
    }
}
like image 914
Dunken Avatar asked Nov 29 '13 07:11

Dunken


1 Answers

  1. MemoryStream is one of the classes that implement IDisposable, because their base class does. MemoryStream doesn't hold any resources (apart from managed memory), so disposing it is actually unnecessary.
  2. HttpResponseMessage is disposable. This means that when the whole response it sent, that object is disposed. Doing that disposes the contained HttpContent, which in the case of StreamContent disposes the underlying Stream. So even if you had a Stream that should be disposed, you don't have to worry about it in this case.
like image 81
svick Avatar answered Nov 04 '22 00:11

svick