Loading a Texture2D throws a NullReferenceException

Hi, I’m trying to load a PNG file as a Texture2D. I use code like this to do that:

Texture2D t  = Content.Load<Texture2D>("tile");

However, this results in NullReferenceException thrown in the Texture2D.DirectX.cs file. It seems that in the PlatformFromStream() method, the bitmap stays null. Also, I filled the method with debug message calls, but none of the ones that are inside the UI thread action get printed out.

EDIT: Forgot to mention, the Stream is not null and has a length, so the file should be loading correctly.

EDIT 2: The aforementioned exception happens when running x86 in an emulator. When I run the ARM build in a device (Lumia 520), it throws an UnAuthorizedAccessException when it tries to call Threading.BlockOnUIThread().

EDIT 3: So, it’s this part the actually never gets called:

Threading.BlockOnUIThread(() =>
{
    BitmapImage bitmapImage = new BitmapImage();
    bitmapImage.SetSource(stream);
    bitmap = new WriteableBitmap(bitmapImage);
});

What version are you using? There was a bug that might have caused this, which was fixed recently. It should work fine with the latest git version.

I just grabbed the zip from github yesterday.

Ahh right, now I get the problem. You cannot load non-xnb textures directly from the functions of the Game class (Initialize, LoadContent, Update, Draw). You have to do it asynchronously, on a different thread.

Sadly this is a limitation of Windows Phone 8 we have been unable to solve. For some reason MonoGame is running a thread different from the main thread on WP8, but invoking something on the main thread from this thread and then awaiting it will cause a deadlock. The same happens here, except the BlockOnUIThread function has a timeout. As a result of time timeout, bitmap will stay null in the Texture2D.FromStream method.

I think I have found a solution of some sort. I changed

protected virtual void LoadContent() { }

to

#if WINDOWS_PHONE
    protected virtual async void LoadContent() { }
#else
    protected virtual void LoadContent() { }
#endif
    protected virtual void UnloadContent() { }

…in the Game.cs file. This seems to remedy the problem.