XNA中的线程处理

3

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

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

我认为创建线程会产生开销,这会导致速度更慢。最后,我写了一个方法,在其中使用while(true){DoNetworkThing();},它将不断循环并重复运行网络调用(它会检查是否已经忙于某个调用,以及是否有要发送的内容)。我在LoadContent方法中的一个线程中调用了该方法,因此它将在自己的线程中与游戏同时运行。但���这样做速度真的很慢。
那么我做错了什么?怎样是最好的方法呢? 谢谢

仅从描述中很难判断。请在您的应用程序中发布示例代码。还请说明您如何测量性能。 - luke
请格式化你的代码。当你发布代码时,你需要选择它并按下101010按钮。 - Kiril
3个回答

13

当我最初尝试在XNA上使用线程时,遇到了完全相同的问题——添加线程会使一切变慢。后来发现是线程亲和力导致了该问题。

在Xbox 360上,默认情况下,所有线程都在同一个处理器核心上运行;这与Windows不同,在Windows中,内核会将线程放置到其他核心上。(有关详细信息,请参见MSDN社区上此主题上的答案。)

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

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

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

在XNA中,Thread.SetProcessorAffinity的文档说明保留了0号和2号核心供框架使用;1号核心和3-5号核心可供您自由使用。主线程(包含main()函数的线程)将位于1号核心。上面的代码随意将线程设置为在3号核心上运行,但您可以选择其他核心,或添加代码来编程选择一个核心(如果您有多个线程,可能需要这样做)。

最后请注意#ifdef保护 - Thread.SetProcessorAffinity仅在Xbox上可用;它甚至不会在Windows上编译!


虽然我还是卡住了,但这是最接近的答案。谢谢 :) - Matt

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. 告诉我们您的机器上有多少个核心。

最后,如果你正在使用线程,我强烈建议你拿起一本关于多线程的好书,真正熟悉其中的概念,完成一些练习并编写一些简单的程序。这可能需要几个月的时间,但如果您不熟悉线程,则可以帮助您学习如何避免许多丑陋的错误。

很多人推荐Joe Duffy的Windows并发编程,但也可以查看其他C#多线程书籍


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接