About the best document I've ever found was http://www.albahari.com/threading/
If I can, the problem with simple examples is that they are often too simple. After you go through the counting or sorting in the background, you usually need to update the user interface or the like, and there are some errors. Similarly, you rarely have to deal with resource conflicts in simple examples, and when threads degrade gracefully, when a resource is inaccessible (like a Db connection), a thought is required.
Conceptually, you need to decide how you are going to distribute your work in threads and how much you need. There, the overhead associated with managing threads and some mechanisms uses a common thread pool, which can be subject to the very conflict of resources (for example, every time you run a program that simply displays an empty form, how many threads you see in the task manager).
So, for your case, the threads performing the actual load should report otherwise if they were completed, if they failed (and what happened with the error). The controller should be able to cope with these processes and manage the start / stop processes, etc.
Finally (almost), assuming that creating something multithreaded will increase performance is not always true. If, for example, you split the file into segments, but it must move along the low-speed channel (ADSL), you are limited by external forces, and no amount of spoofed streams will cost. The same can be applied to database updates, web requests, anything that requires large amounts of disk I / O, etc.
Despite all this, I am not a prophet of death. The links here are more than sufficient to help you achieve what you want, but remember that one of the reasons why threads seem complicated is that it can be :)
If you want more control than BackgroundWorker / Threadpool but donโt want to do everything yourself, there are at least two very good niche stream libraries that knock around the place (Wintellect and PowerThreading).
Greetings
Simon