Search code examples
c#asp.net-web-apitask-parallel-libraryusing

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???
        });
    }
}

Solution

    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.