PersistantStorage Throws System.IO.IOException from SPOT.IO.RemovableMedia::MessageHandler

If your program gives this exception: (Not any IO exception applies. Note where the exception is coming from)

Your program and storage device are fine. The exception is harmless and can be ignored.
In normal applications this exception.

It happens because of controlling the Unmount and it is being done too fast. For example:


PersistentStorage sd = new PersistentStorage("SD");
sd.MountFileSystem();

// you might have few statements here
// ...

sd.UnmountFileSystem();

//....
// you might see the exception here

When you mount the the file system, Micro Framework tries to send a RemovableMedia.Insert event in a seperate thread,
but if you unmount before the event is sent, an exception will occur in a seperate thread. Your main application wil continue normally.

How to avoid it?
-Standard applications should access the SD card after the insert event is sent. For example:


using System;
using System.IO;
using System.Threading;

using Microsoft.SPOT;
using Microsoft.SPOT.IO;

using GHIElectronics.NETMF.IO;

namespace Test
{
    class Program
    {
        // Hold a static reference in case the GC kicks in and disposes it automatically, note that we only support one in this example!
        static PersistentStorage ps;

        public static void Main()
        {
            // Subscribe to RemovableMedia events
            RemovableMedia.Insert += RemovableMedia_Insert;
            RemovableMedia.Eject += RemovableMedia_Eject;

            // Assume SD card is inserted
            // Create a new storage device
            ps = new PersistentStorage("SD");
            ps.MountFileSystem();

            // Sleep forever
            Thread.Sleep(Timeout.Infinite);
        }

        static void RemovableMedia_Insert(object sender, MediaEventArgs e)
        {
            Debug.Print("Storage \"" + e.Volume.RootDirectory + "\" is inserted.");
            Debug.Print("Getting files and folders:");
            if (e.Volume.IsFormatted)
            {
                string[] files = Directory.GetFiles(e.Volume.RootDirectory);
                string[] folders = Directory.GetDirectories(e.Volume.RootDirectory);

                Debug.Print("Files available on " + e.Volume.RootDirectory + ":");
                for (int i = 0; i < files.Length; i++)
                    Debug.Print(files[i]);

                Debug.Print("Folders available on " + e.Volume.RootDirectory + ":");
                for (int i = 0; i < folders.Length; i++)
                    Debug.Print(folders[i]);
            }
            else
            {
                Debug.Print("Storage is not formatted. Format on PC with FAT32/FAT16 first.");
            }

            // We do not need it any more
            ps.Dispose();
        }

        static void RemovableMedia_Eject(object sender, MediaEventArgs e)
        {
            Debug.Print("Storage \"" + e.Volume.RootDirectory + "\" is ejected.");
        }
    }
}

-The application should not unmount right after a mount. The exception usually occurs if you unmount fast like within 100 ms.
-You can put a delay before unmount.


sd.MountFileSystem();

// you might have few statements here
// ...

// delay to avoid exception
Thread.Sleep(500);
sd.UnmountFileSystem();