Как говорит Рид, это действительно зависит от контекста. Код должен выполняться с некоторой точкой - но в зависимости от контекста он может в конечном итоге выполняться в потоке пула потоков, а не в каком-то критическом.
Вместо использования Task.Run
я бы использовал TaskEx.Yield
:
public async Task Foo()
{
await TaskEx.Yield();
// Do expensive stuff
}
Насколько я знаю, это в основном способ немедленного возврата к вызывающей стороне, но позволяет сразу запланировать оставшуюся часть асинхронного метода. Если вы находитесь в чем-то вроде потока пользовательского интерфейса Windows Forms, нет смысла делать это, поскольку вы сразу же вернетесь к потоку пользовательского интерфейса (и выполняете там дорогой код) - но это будет иметь смысл, если вы находитесь в контексте где текущий поток не должен быть заблокирован, но продолжения выполняются в другом потоке.