2012-09-29 52 views
1

我是新来的多线程,所以暂时搁置所有其他问题。我在解决我的sprite批处理问题时遇到了困难,因为更快的线程和下一个线程导致“对象引用未设置为对象的实例”。C#XNA多线程SpriteBatch.End()“对象引用未设置为对象的实例”

哦,如果你能看到什么都错我的代码随意让我觉得自己像个白痴^^

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是谁决定了它是使用4个空格来表示代码,而不是一个好主意[code] [/ code]的? ¬_¬

+0

欢迎来到StackOverflow :-)帖子的格式使用Markdown(我觉得这很不错),所以这就是4格式的来源。有关更多详细信息,请参阅http://stackoverflow.com/editing-help。 –

回答

0

图形设备一次只能由一个线程访问,并且SpriteBatch不是线程安全的,所以您的绘图调用应该从主线程发送。

如果你想优化你的代码绘制多个对象,DrawInstancedPrimitives就会干净得多

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

有谁知道我为什么会出现更多的口吃,并且通常使用多线程降低fps?使用1个螺纹程序阻塞280k颗粒,2个螺纹210k,3个螺纹180k。此外,绘图代码是目前仅使用1个内核的瓶颈,所以我仍然不理解多线程框架下降和口吃。我有一个i5-2500k @ 4.0GHz,4x4GB 1600MHz RAM,HD 6870 1GB,256GB C4 SSD。 – Shaun

+0

@catflier Instancing对于精灵来说是一个非常糟糕的选择。如果这是一个不错的选择,那么'SpriteBatch'就会在内部使用这种技术。实际模型时,实例化效果更好。但是你说只能从主线程中抽取,你当然是正确的。 –

3

你的问题来自于一个事实,即SpriteBatch不是线程安全的。通过写入来自多个线程的一个精灵批处理,你正在破坏它。

SpriteBatch(除Immediate模式)的工作原理有点像精灵的List(您将无法访问这些从多个线程中的一个,你会吗?),或精灵的缓冲区。所以一个可能的解决方案是每个线程有一个SpriteBatch。通过在该线程内部调用Draw来填充每个精灵批处理“缓冲区”。

然后,因为您只能在主线程上绘制东西(即:您只能在主线程上调用GraphicsDevice.Draw*,这是SpriteBatch.End在内部调用的东西),请等待工作线程完成每个批处理,然后请从主线程调用End。这会将精灵画到屏幕上。当然,更好的技术,如果你想绘制大量的粒子,可能会把所有东西都卸载到GPU上。 Here is an answer,它给你一个粗略的指导,你可能会这样做。

相关问题