在XNA中进行线程化

时间:2010-07-01 23:44:27

标签: c# multithreading xna

我在XNA中有一个需要进行网络通话的游戏。在更新方法中,我确定需要发送的内容,然后将其添加到要发送的内容列表中。然后我运行网络呼叫。这显然会减慢应用程序的速度。所以我首先尝试在更新中创建一个这样的新线程,使其在一个单独的线程上执行:

Thread thread; 
thread = new Thread(
new ThreadStart(DoNetworkThing));
thread.Start();

我认为创建线程有开销等,导致这甚至更慢。 最后,我创建了一个方法,其中包含while(true){DoNetworkThing();},它将循环并一遍又一遍地运行网络调用(它会检查它是否已经忙于一个,以及是否有要发送的东西)。我在一个线程中调用LoadContent方法的方法,因此它将在自己的线程中与游戏一起运行。 但那也很慢。

那么我做错了什么?这样做的最佳方式是什么? 感谢

3 个答案:

答案 0 :(得分:13)

我最初尝试在XNA上使用线程时遇到了这个问题 - 添加一个线程会减慢一切。事实证明线程亲和力是个问题。

在Xbox 360上,默认情况下,所有线程都在同一处理器核心上运行;此行为与Windows不同,后者内核将线程放置到其他内核上。 (有关详细信息,请参阅MSDN社交网站this thread上的答案。)

要解决这个问题,您需要将线程的亲和力设置为线程函数中的另一个核心:

void DoNetworkThing()
{
#ifdef XBOX
    Thread.SetProcessorAffinity(3); // see note below
#endif
    /* your code goes here */
}

Thread thread = new Thread(
 new ThreadStart(DoNetworkThing));
thread.Start();

Thread.SetProcessorAffinity的文档说明在XNA上,核心0和2是为框架保留的;核心1和核心3-5免费供您使用。主线程(包含main()函数的线程)将位于核心1.上面的代码任意设置线程在核心3上运行,但您可以选择不同的核心,或添加代码以编程方式选择核心(如果你有多个线程,你可能想要这样做。)

最后,请注意#ifdef后卫 - Thread.SetProcessorAffinity仅适用于Xbox;它甚至不会在Windows上编译!

答案 1 :(得分:1)

好的,首先 - 创建一个新线程确实有一些最小的开销,但你只创建一次(或几次)...所以除非你是创建数百个线程(你不应该这样做),那么你就不必担心开销了。

让我们看看你的第一个例子:

Thread thread; 
thread = new Thread(new ThreadStart(DoNetworkThing));

// you should set the thread to background, unless you 
// want it to live on even after your application closes
thread.IsBackground = true;
thread.Start();

如果您坚持使用该模型,DoNetworkThing函数将如下所示:

void DoNetworkThing()
{
    while(someConditionIsTrue)
    {
        // do the networking stuff here
    }
}

我认为在你的下一次尝试中你做了类似的事情:

Thread thread = new Thread(()=>
   {
       while(true)
       {
           DoNetworkThing();
       }
   });
thread.IsBackground = true;
thread.Start();

这两种方法都很好,但唯一的区别是DoNetworkingThing的内容。在第二种方法中,它将如下所示:

void DoNetworkThing()
{
    // do the networking thing, but note
    // that this time your infinite while
    // loop is outside the function
}

现在您说这两种尝试都非常缓慢,但您的示例中没有任何内容表明应该有任何明显的性能影响。如果可以,那就太棒了:

  1. 举个例子来说明减速。
  2. 告诉我们您运行游戏的计算机上有多少核心。
  3. 最后,如果你正在混合线程,那么我强烈建议你找一本关于多线程的好书,真的熟悉它背后的概念,去吧通过练习并编写几个简单的程序。这将花费你几个月的时间,但如果你不熟悉线程,那么它将帮助你学习如何避免许多丑陋的错误。

    很多人推荐Joe Duffy的Concurrent Programming on Windows,但也可以随时查看some other C# multithreading books

答案 2 :(得分:0)

检查使用ThreadPool是否可以提高性能可能是值得的。创建许多线程可能很昂贵。

http://msdn.microsoft.com/en-us/library/h4732ks0(v=vs.100).aspx