In any method returning a Task, it is desirable to avoid using Task.Run if you can compute a result without going async. For example, if logic allows you to short-circuit a computation, or if you have a fake method in a test returning a pre-computed answer, then you don't need to use Task.Run.
Example:
Here is a method that is not going to do any work, but needs to return a task to fulfill an interface contract for a test:
public Task ComputationWithSideEffects(string someId) { return Task.Run(() => { // i'm just here to simulate hard work }); }
Instead of returning the result of Task.Run, there are two helpers on the Task class that make the code more readable and require a bit less runtime overhead.
For the above scenario, I'd rather use Task.CompletedTask:
public Task ComputationWithSideEffects(string someId) { return Task.CompletedTask; }
What if the caller expects to receive a result from the task? In other words, what if you return a Task<T>? In this scenario, if you already have an answer, use Task.FromResult to wrap the answer.
public Task<Patience> FindPatience() { if(cachedPatience != null) { return Task.FromResult(cachedPatience); } else { return ImAlreadyGone(); } }