1

我是多线程的新手,所以暂时搁置所有其他问题。我无法解决如何解决我的精灵批处理被更快的线程和下一个线程导致“对象引用未设置为对象的实例”的问题。

哦,如果您发现我的代码有任何其他问题,请随时让我觉得自己像个白痴^^

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] 是个好主意?¬_¬

4

2 回答 2

3

您的问题来自SpriteBatch不是线程安全的事实。通过从多个线程写入一个精灵批次,您正在破坏它。

SpriteBatchImmediate模式除外)有点像List精灵(你不会从多个线程访问其中一个,对吗?)或精灵缓冲区。因此,一个可能的解决方案是SpriteBatch为每个线程设置一个。Draw通过在该线程内部调用来填充每个精灵批次“缓冲区” 。

然后,因为你只能在主线程上绘制东西(即:你只能GraphicsDevice.Draw*在主线程上调用,这是SpriteBatch.End内部调用的),等待你的工作线程完成每个批次的填充,然后End从它们中调用它们中的每一个主线程。这会将精灵绘制到屏幕上。

当然,如果您想绘制大量粒子,更好的技术可能是将所有内容卸载到 GPU 上。这是一个答案,可为您提供有关如何执行此操作的粗略指南。

于 2012-09-30T11:48:52.340 回答
0

Graphics Device 一次只能被一个线程访问,并且 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

于 2012-09-29T15:08:13.713 回答