2

I'm using MonoGame, but this is related more to winrt async and IO, so please don't redirect to gamedev.

I want to load game content asynchronously so that I can update the progress of a loading screen. I placed each ContentManager.Load call inside a Task and then inside my BeginLoading method, I just iterate over all of the tasks and start them in one shot.

This seems to work from my testing so far, but my question is whether or not this scales.

If I add 100 assets for async, this will spin off 100 tasks that will read from the disk al at the same time. Does WinRT scale like that?

In fact, should I just limit the number of tasks to the number of cores/physical treads? Or should I just have only one active Task altogether?

RecursiveCall
  • 482
  • 3
  • 13
  • Why not just have a single task that loads all the content? – craftworkgames Jul 22 '13 at 22:34
  • I update the loading progress (percentage loaded) based on the number of completed tasks. It's also easier to create a task per Content.Load call. Unless someone has a better suggestion. – RecursiveCall Jul 23 '13 at 15:49

1 Answers1

1

Creating 100 tasks will not necessarily start 100 concurrent threads that all execute at the same time. You're limited to the number of pool threads available and also to what the TPL things is a reasonable number of tasks to be running concurrently. On a 4-core machine, it's likely you won't get more than three or four concurrent tasks.

That said, you're probably better off starting a single task that then iterates over your list of assets and loads them one at a time. With multiple threads making I/O requests to the same drive, it's likely that those threads will spend a lot of time waiting on the disk and don't do much in the way of concurrent processing. You're getting little to no benefit from having many threads do the loading, because they spend most of their time idle. I wouldn't be surprised to find that your multiple loader threads take longer to complete than if you started a single thread that loads all the assets one at a time.

I don't see how creating 100 individual tasks, each one loading a single asset, can be any easier to code than a single task that loads those 100 assets sequentially. I can't think of how you could create such a data structure.

In short, you don't have to limit your number of tasks to the number of available cores; the TPL will do that for you. But you're probably better off having a single task. At best, you'd be marginally better off with multiple concurrent threads, but it's unlikely.

Jim Mischel
  • 131,090
  • 20
  • 188
  • 351
  • The fact that TPL manages the number of threads against the number of cores available addressed most of my concern. The question remaining is how would you update the estimated progress from a single thread? It seems more complicated than simply looking at the count of the remaining vs completed threads. – RecursiveCall Jul 27 '13 at 19:48
  • @RecursiveCall, if you know how many resources you have to load and you know how many you loaded, what's the problem? – Jim Mischel Jul 27 '13 at 20:08
  • Ah, the problem now is a bit more specific to the way MonoGame/XNA load assets (I need to pass a string and T to the Load method). I guess this is more of a generic C# question. – RecursiveCall Jul 27 '13 at 20:42