Start here. This is the direct spoken answer to practice first.
Why this question matters
Task.Run schedules work on the thread pool; async/await composes operations that may already be asynchronous. Confusing the two can hide blocking dependencies, waste worker capacity, and reduce server throughput.
I use async/await directly for I/O-bound operations that already expose async APIs, like database calls or HTTP requests. I use Task.Run mainly when I need to run CPU-bound work on a thread-pool thread from a context where that makes sense. In ASP.NET Core, wrapping normal I/O in Task.Run is usually a mistake because it consumes extra thread-pool capacity instead of improving scalability.