我在XNA中有一个需要进行网络通话的游戏。在更新方法中,我确定需要发送的内容,然后将其添加到要发送的内容列表中。然后我运行网络呼叫。这显然会减慢应用程序的速度。所以我首先尝试在更新中创建一个这样的新线程,使其在一个单独的线程上执行:
Thread thread;
thread = new Thread(
new ThreadStart(DoNetworkThing));
thread.Start();
我认为创建线程有开销等,导致这甚至更慢。
最后,我创建了一个方法,其中包含while(true){DoNetworkThing();}
,它将循环并一遍又一遍地运行网络调用(它会检查它是否已经忙于一个,以及是否有要发送的东西)。我在一个线程中调用LoadContent方法的方法,因此它将在自己的线程中与游戏一起运行。
但那也很慢。
那么我做错了什么?这样做的最佳方式是什么? 感谢
答案 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
}
现在您说这两种尝试都非常缓慢,但您的示例中没有任何内容表明应该有任何明显的性能影响。如果可以,那就太棒了:
最后,如果你正在混合线程,那么我强烈建议你找一本关于多线程的好书,真的熟悉它背后的概念,去吧通过练习并编写几个简单的程序。这将花费你几个月的时间,但如果你不熟悉线程,那么它将帮助你学习如何避免许多丑陋的错误。
很多人推荐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