File IO should be using asynchronous methods too. If your OS doesn't support asynchronous file IO then you're not using any of the big 3.
Exactly this. You want one thread pool of size ~= core count, then you want to have a completely different "max number of IO jobs" type deal that doesn't use threads at all.
C# async/await is pretty good for this (IO operations do not count towards CPU task count).