Are there good rule(s) for when to use Task.Delay versus Thread.Sleep?
Use Thread.Sleep
when you want to block the current thread.
Use Task.Delay
when you want a logical delay without blocking the current thread.
Efficiency should not be a paramount concern with these methods. Their primary real-world use is as retry timers for I/O operations, which are on the order of seconds rather than milliseconds.