1

I'm developing an app for WP8. In a ScheduledTaskAgent I need to download an image from internet, save it to storage, after that I load the same image and do some processing. I am facing the dreaded OutOfMemoryException. If I remove the "download and save image" (using an already saved image) part, it all works. If I just download and save, it all works. Maybe in the first schedule I can save it, in the second process. But I do not understand where or why my download image is holding memory so, can anyone suggest me a better way to do this? Here is my actual code:

    private async Task GetImage(string url)
    {
        using (var http = new HttpClient())
        {
            var clientResponse = await http.GetByteArrayAsync(url);

            var file = await ApplicationData.Current.LocalFolder.CreateFileAsync(lockFilename, Windows.Storage.CreationCollisionOption.ReplaceExisting);
            using (var fs = await file.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite))
            {
                var outStream = fs.GetOutputStreamAt(0);
                using (var dataWriter = new Windows.Storage.Streams.DataWriter(outStream))
                {
                    dataWriter.WriteBytes(clientResponse);
                    await dataWriter.StoreAsync();
                    dataWriter.DetachStream();
                    await outStream.FlushAsync();
                    outStream.Dispose(); 
                    fs.Dispose();
                }
            }
        }
    }
slugster
  • 49,403
  • 14
  • 95
  • 145
Leo
  • 7,379
  • 6
  • 28
  • 44
  • 5
    You need to stream it down.. not download the whole thing in bulk. – Simon Whitehead Mar 12 '14 at 02:54
  • possible duplicate of [Download/Stream file from URL - asp.net](http://stackoverflow.com/questions/5596747/download-stream-file-from-url-asp-net) – bradgonesurfing Mar 12 '14 at 08:12
  • Why are you calling `Dispose` and using `using`. And why are you calling `Dispose` instead of using `using`? – Paulo Morgado Mar 12 '14 at 09:18
  • 1
    Have you tried [`Stream.CopyToAsync(Stream)`](http://msdn.microsoft.com/library/hh159084.aspx "Stream.CopyToAsync Method (Stream)")? – Paulo Morgado Mar 12 '14 at 09:20
  • Simon, thank you for your suggestion - this indeed was the right way. I can load all the image in memory and it works, the problem is that .net did not releases all that used memory when I wanted... but streaming it (like is suggested here: http://stackoverflow.com/questions/16140733/download-image-in-windows-phone-8) worked. – Leo Mar 12 '14 at 14:35
  • @bradgonesurfing, maybe it can be a duplicate answer but the question are different. I would not get there from where I was.... – Leo Mar 12 '14 at 14:37
  • @PauloMorgado I tried all combinations of using and disposing, to see if it made a difference - it did not. – Leo Mar 12 '14 at 14:38
  • @Leo, I wouldn't expect it to. That's why I posted as a separate comment. – Paulo Morgado Mar 12 '14 at 14:41

1 Answers1

0

By using HttpClient.GetStreamAsync you will get access directly to the network stream and you can copy that stream to the filestream. This should reduce the memory consumption.

Darrel Miller
  • 139,164
  • 32
  • 194
  • 243