2012-09-29 1 views
1

Je suis novice en matière de multi-threading, donc tous les autres problèmes de côté. Je n'arrive pas à résoudre comment résoudre mon lot de sprite étant terminé par le thread le plus rapide et le thread suivant provoquant "Référence d'objet n'est pas définie sur une instance d'un objet".C# XNA Multi-threading SpriteBatch.End() "Référence d'objet non définie sur une instance d'un objet"

Oh, et si vous pouvez voir toute autre chose ne va pas avec mon code ne hésitez pas à me faire sentir comme un idiot ^^

spriteBatch.Begin(); 

// Draw Particles 
List<Thread> threads = new List<Thread>(); 
for (int i = 0; i < CPUCores; i++) 
{ 
    int tempi = i; // This fixes the issue with i being shared 
    Thread thread = new Thread(() => DrawParticles(tempi + 1, CPUCores)); 
    threads.Add(thread); 
    thread.Start(); 
} 
foreach (var thread in threads) 
{ 
    thread.Join(); 
} 

// ..More Drawing Code.. 

spriteBatch.End(); // <-- This is where the program crashes 

PS Qui a décidé qu'il était une bonne idée d'utiliser 4 espaces pour signifier à la place du code de [code] [/ code]? ¬_¬

+0

Bienvenue dans StackOverflow :-) la mise en forme des articles utilise Markdown (que je trouve plutôt sympa) et c'est de là que vient la mise en forme des 4 espaces. Voir http://stackoverflow.com/editing-help pour plus de détails. –

Répondre

0

Graphics Device n'est accessible que par un thread à la fois, et SpriteBatch n'est pas thread-safe, donc vos appels draw doivent être envoyés à partir du thread principal.

Si vous souhaitez optimiser votre code pour dessiner plus d'objets, DrawInstancedPrimitives sera beaucoup plus propre

http://blogs.msdn.com/b/shawnhar/archive/2010/06/17/drawinstancedprimitives-in-xna-game-studio-4-0.aspx

http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.graphicsdevice.drawinstancedprimitives.aspx

+0

Est-ce que quelqu'un sait pourquoi je reçois plus de bégaiement et généralement moins de fps en utilisant le multithreading? En utilisant 1 thread le programme étouffe autour de 280k particules, 2 threads 210k, 3 threads 180k. Aussi le code de dessin est le goulot d'étranglement pour le moment en utilisant seulement 1 core donc je ne comprends toujours pas le cadre de multithreading gouttes et bégaiement. J'ai un i5-2500k @ 4.0GHz, RAM 4x4GB 1600MHz, HD 6870 1Go, 256Go C4 SSD. – Shaun

+0

@catflier L'instanciation est vraiment un mauvais choix pour les sprites. Si c'était un bon choix, 'SpriteBatch' utiliserait déjà la technique en interne. L'instanciation est meilleure quand vous avez des modèles réels. Mais vous avez certainement raison de dire que vous ne pouvez tirer que du fil principal. –

3

Votre problème vient du fait que SpriteBatch n'est pas thread-safe. En écrivant dans un sprite-batch à partir de plusieurs threads, vous le corrompez.

SpriteBatch (sauf en mode Immediate) fonctionne comme une sorte de List de sprites (vous pas accéder à l'un de ceux de plusieurs threads, vous?) Ou un tampon de sprites. Donc, une solution possible à cela est d'avoir un SpriteBatch pour chaque thread. Remplissez chaque «lot» de sprite batch en appelant Draw à l'intérieur de ce thread. Puis, parce que vous ne pouvez dessiner que des choses sur le thread principal (ie: vous pouvez seulement appeler GraphicsDevice.Draw* sur le thread principal, ce que SpriteBatch.End appelle en interne), attendez que vos threads de travail finissent de remplir chaque batch, puis appelez End sur chacun d'eux à partir du fil principal. Cela va attirer les sprites à l'écran.

Bien sûr, une meilleure technique, si vous voulez dessiner un très grand nombre de particules, pourrait être de tout décharger sur le GPU. Here is an answer qui vous donne un guide approximatif sur la façon dont vous pourriez faire cela.

Questions connexes