2010-07-01 35 views
3

我在XNA有一個需要做網絡調用的遊戲。在更新方法中,我確定需要發送的內容,然後將其添加到要發送的內容列表中。然後我運行網絡通話。這顯然減慢了應用程序。所以我第一次嘗試在更新制作這樣一個新的線程來讓它做它在一個單獨的線程:在XNA中的線程

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

我相信創建線程具有開銷等,這導致在這之中更慢。 最後,我做了一個方法,其中有while(true){DoNetworkThing();}它將繼續循環並反覆運行網絡呼叫(它確實檢查它是否已經忙於一個,以及是否有東西要發送)。我在一個線程的LoadContent方法中調用了這個方法,所以它會在它自己的線程中與遊戲一起運行。 但是這真的很慢。

那麼我做錯了什麼?這樣做的最好方法是什麼? 感謝

+0

它的將是很難單從描述出來。請從您的應用程序中發佈示例代碼。還請包括你如何衡量你的性能 – luke 2010-07-02 00:51:27

+0

請格式化你的代碼。當您發佈代碼時,您需要選擇它並按101010按鈕。 – Kiril 2010-07-02 04:29:57

回答

13

當最初嘗試在XNA上使用線程時,我有這個確切的問題 - 添加一個線程減慢了一切。原來,線程親和力是問題。

在Xbox 360上,默認情況下,所有線程都運行在同一處理器內核上;這種行爲與Windows不同,在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上編譯!

+0

儘管我仍然堅持下去,但這是最接近的答案。謝謝 :) – Matt 2010-07-02 21:57:56

1

OK,所以首先清一色創建一個新的線程確實有一些最小開銷,但你只能創建線程一次(或幾次)...所以,除非你正在創建數百個的線程(你不應該這樣做),那麼你不需要擔心開銷。

讓我們看看你的第一個例子:

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(); 

這兩種方法都很好,b唯一的區別是DoNetworkingThing的內容。在第二種方法將是這樣的:

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

現在你說,無論這些嘗試是很慢的,但在你的例子給出任何將表明,應該有任何明顯的性能影響。如果你能夠:

  1. 給我們一個例子,它會證明減速。
  2. 告訴我們在遊戲機上運行的機器上有多少核心。

最後,如果你正在使用線程交融,那麼我會強烈建議你拾一本好書多線程和真的熟悉它背後的概念,經過練習,寫一對夫婦簡單的程序。這將花費你幾個月的時間,但如果你不熟悉線程,那麼它將幫助你學習如何避免很多醜陋的錯誤。

很多人推薦Joe Duffy的Concurrent Programming on Windows,但隨時也可以檢查some other C# multithreading books