2013-07-22 130 views
1

我正在使用MonoGame,但這與winrt async和IO更相關,所以請不要重定向到gamedev。IO操作與Task.Run

我想異步加載遊戲內容,以便我可以更新加載屏幕的進度。我將每個ContentManager.Load調用放置在一個Task中,然後放入我的BeginLoading方法中,我只是遍歷所有任務並一次啓動它們。

這似乎從我的測試到目前爲止,但我的問題是這是否縮放。

如果我爲async添加100個資產,這將分離出100個將同時從磁盤al讀取的任務。 WinRT的規模是那樣嗎?

事實上,我是否應該將任務的數量限制在覈心數/物理踏步數?或者我應該只有一個活動的任務?

+0

爲什麼不只有一個加載所有內容的任務? – craftworkgames

+0

我根據完成的任務數更新加載進度(加載的百分比)。 根據Content.Load調用創建任務也更容易。除非有人有更好的建議。 – RecursiveCall

回答

1

創建100個任務不一定會啓動100個同時執行的併發線程。您僅限於可用池線程的數量,以及TPL事物是同時運行的合理數量的任務。在4核機器上,很可能你不會得到超過三個或四個併發任務。

也就是說,您可能最好啓動一個單一的任務,然後迭代您的資產列表並逐個加載它們。由於多個線程向同一個驅動器發出I/O請求,這些線程很可能會花費大量的時間在磁盤上等待並且不會在併發處理方面做很多事情。由於有很多線程進行加載,你沒有多少好處,因爲他們大部分時間都是空閒的。如果您發現多個加載器線程需要更長的時間才能完成,那麼我不會驚訝地發現,如果您啓動的是一次加載所有資源的單個線程,則可能需要更長的時間。

我沒有看到如何創建100個單獨的任務,每個任務加載一個資產,比單獨加載這100個資產的任務更容易編碼。我想不出如何創建這樣的數據結構。

總之,您不必將任務數量限制爲可用核心數量; TPL會爲你做到這一點。但是你可能會有更好的單一任務。充其量,最好是邊際與多個併發線程更好,但它不太可能。

+0

TPL根據可用內核數量管理線程數量,這一事實解決了我最關心的問題。剩下的問題是如何更新單線程的估計進度?看起來比簡單地看剩餘vs完成線程的數量更復雜。 – RecursiveCall

+0

@RecursiveCall,如果你知道你需要加載多少資源,並且你知道你加載了多少,那麼問題是什麼? –

+0

嗯,現在的問題是MonoGame/XNA加載資產的方式更具體一些(我需要將一個字符串和T傳遞給Load 方法)。我想這更多的是一個通用的C#問題。 – RecursiveCall