Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

While playing, I use a thread to Load() and Unload() Texture2D. I have multiple ContentManager to only Unload() Texture2D I want to unload.

But sometimes, I have this issue on the SpriteBatch.End() :

    ObjectDisposedException: Cannot access a disposed object
    Object name : texture2D

I don't understand very well the Threads, and I think it's the main problem. Roughly :

    Game.Update(GameTime gameTime)
    {
        character.Update(gameTime);
        //...Things.Update(gameTime)...
        CheckThingsToLoadandUnload();
    //etc
    }

    CheckThingsToLoadAndUnload()
    {
        For each texture to check
        {
            if(HasPrerequists)
            {
                if(!thisTexture.isLoaded)
                {
                    ThreadStart ths_LoadInGame = delegate {
                        LoadInGame(param1, param2, param3); };
                    new Thread(ths_LoadInGame).Start();
                }
            }
            else
            {
                if(thisTexture.isLoaded)
                {
                    ThreadStart ths_UnloadInGame = delegate {
                        UnloadInGame (param1, param2); };
                    new Thread(ths_UnloadInGame ).Start();
                }
            }
        }
    }

I overrided the T Load<T<(string assetname) ContentManager to add a Lock.

I think this issue happens when the Unload() Thread unload a Texture used by the SpriteBatch(). But I really don't know how to prevent this. Hope you can help.

share|improve this question
1  
Just because the CPU portion of a Draw call has completed doesn't mean the GPU has finished rendering. Any textures used in the last Draw call could still be in memory and in use on the GPU. You will want to delay disposing any textures for at least a few draw calls after they were last used. –  dadoo Games Feb 21 '13 at 15:24
1  
You will also not want to spawn a new thread for loading and unloading each individual asset. The overhead of spawning threads is too high. It would be much better to have one dedicated thread handling loading and unloading of assets, but even then you need to be aware of graphic device locks negating your threaded logic. See here blogs.msdn.com/b/shawnhar/archive/2008/05/23/… –  dadoo Games Feb 21 '13 at 15:29
    
@dadooGames How to know if the Texture-I-want-to-unload is in use on the gpu ? With my example, how to keep a thread on ? Sorry, but I feel lost. (about your link, yes, I already use this for my loading screen) –  Sharpnel Feb 21 '13 at 20:52
    
@dadooGames I don't think the base.draw() method returns before the GPU is finished. As far as I know XNA does not use a form of threaded rendering. Do you have a source for this? –  Roy T. Feb 21 '13 at 21:18
    
In XNA, Draw() won't return until all the appropriate commands are sent to the GPU, but it does not wait for the GPU to execute them before moving on to the next frame. I can't find a good reference, other than this slightly related link that is all about XNA without saying XNA at all blogs.msdn.com/b/shawnhar/archive/2008/03/31/… –  dadoo Games Feb 22 '13 at 3:57
show 3 more comments

1 Answer

up vote 0 down vote accepted

With the participation of "dadoo Games", here is my answer.

Thread :

Unload()
{
   if(canUnload) { UnloadTextures() }
}

DrawMethod :

Draw(GameTime gameTime)
{
    canUnload = false;
    DrawScenes();
    base.Draw(GameTime);
    canUload = true;
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.