1

Sometimes(i haven't found pattern yet) i get NullReferenceException while i am trying to save picture to media library. Problem is in method SavePicture i simply use this.

using (var isoStore = IsolatedStorageFile.GetUserStoreForApplication())
{
    if (isoStore.FileExists("fileName"))
    {
        using (var fileStream = isoStore.OpenFile("fileName", FileMode.Open))
        {
            MediaLibrary library = new MediaLibrary();
            library.SavePicture("name", fileStream);
        }
    }
}

fileStream is as you can see from code IsolatedStorageFileStream and is valid and not null. This is my stack trace

at Microsoft.Xna.Framework.Media.UnsafeNativeMethods.MediaLibrary_SavePicture(String name, Int32 nameLength, UInt32 stream, UInt32& picture)
at Microsoft.Xna.Framework.Media.MediaLibrary.SavePicture(String name, Stream source)

From Position property in stream i can see that its not 0 so i am assuming that same part of stream was already saved but while buffering for more something wrong happened. it always happen on big images(+4MB) but not necessarily on same picture every time exception is thrown and i am using same collection of pictures. If i catch the exception and i try to save picture again without opening file again just with same stream(i only have to set Position to 0) then picture is saved without any problems.

Any ideas? Any help would be appreciated.

Tomas Kosar
  • 394
  • 1
  • 10
  • 23
  • Please review [this question](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) and see if you have covered the standard bases. If so, please try to add that detail to this question to differentiate it from the standard "something is null" error. – Adam Houldsworth Apr 02 '14 at 09:24
  • @Tom Kos change FileMode Opent to Read. – Jaihind Apr 02 '14 at 09:24
  • @Adam Houldsworth: I check out that question and answers but I think that i know what this exception means and i think i posted all details that i could provide and are relevant in this case. Exception is thrown from method SavePicture and i believe that my input is correct. i think there might be some problem inside this method... – Tomas Kosar Apr 02 '14 at 09:35
  • @Jaihind: i will try that and i will test it but i am not sure if it would be any different and if it could help. – Tomas Kosar Apr 02 '14 at 09:36
  • @TomKos Fair enough, I was just heading off the "close as duplicate" option as `NullReferenceException` questions tend to always result in something simple. As is becoming evident, this case isn't immediately straightforward. Hopefully people will read this and avoid the urge to close :-) – Adam Houldsworth Apr 02 '14 at 09:40
  • @Adam Houldsworth : raja found whats the problem. its known bug apparently. – Tomas Kosar Apr 02 '14 at 09:45
  • @TomKos Yes I see, but please note that the code be provided probably won't compile as you cannot cast `IsolatedStorageFileStream` to `MemoryStream` so far as I'm aware. – Adam Houldsworth Apr 02 '14 at 09:45
  • @Adam Houldsworth: i did not try that but that is not important to me. I get the point of what raja is saying to use array instead of stream but as i said it might not be the best solution in my case. – Tomas Kosar Apr 02 '14 at 09:49
  • 2
    @TomKos Fair enough, but it is important to SO to provide integral answers for future visitors. I've removed the uncompilable code at any rate. – Adam Houldsworth Apr 02 '14 at 09:50

1 Answers1

1

This is a known bug with some of the MediaLibrary methods. Normally happens for big images in the size range of 4 to 16 MB.

Not sure of the bug fix status. Here is the connect link: http://connect.microsoft.com/VisualStudio/feedback/details/776453/savepicturetocameraroll-randomly-throws-nullreferrenceexception

One of the workarounds to mitigate the issue is to use the memory stream, if your code is in the UI thread and not in any worker thread:

using (var isoStore = IsolatedStorageFile.GetUserStoreForApplication())
{
    if (isoStore.FileExists("fileName"))
    {
        using (var fileStream = isoStore.OpenFile("fileName", FileMode.Open))
        {
            byte[] bytes = new byte[0]; // Read bytes from fileStream

            MediaLibrary library = new MediaLibrary();
            library.SavePicture("name", bytes);
        }
    }
}

Other wprkarounds include doing a GC.Collect() before calling this method, using a try/catch to retry AND finally reduce the size of the image if possible.

Adam Houldsworth
  • 63,413
  • 11
  • 150
  • 187
Raja Nadar
  • 9,409
  • 2
  • 32
  • 41
  • 1
    `IsolatedStorageFileStream` (from `OpenFile`) cannot be cast to `MemoryStream` like that. The bytes will have to be read out manually into a memory stream or `byte[]` to be provided to the `SavePicture(string, byte[])` method. – Adam Houldsworth Apr 02 '14 at 09:43
  • ok so its exactly what i was afraid of. but thanks for clarify. i wasn't able to found that by myself but i was looking for different method and i assume they are more or less the same. I was thinking about using array too but i will have problems with holding so much memory in same cases. Anyway thats my problem and i will probably stick with my workaround of just trying to save it multiple times if its necessary. – Tomas Kosar Apr 02 '14 at 09:43