В чем разница между Task.FromException и throw?

Допустим, есть метод, который возвращает задачу.

В чем разница между тем, чтобы просто бросить исключение или сделать Task из исключения и её вернуть?

Разве в обоих случаях вызывающие код не получит один и тот же Task?

В каких случаях имеет смысл делать Task из исключения?

Лично я вижу какой-то очень специфический случай, когда просто возвращается какая-то коллекция Task`ов, часть из которых не запустились из-за корявых конфигов и тогда можно вернуть Task с объяснением причин и уже вызывающие код их анализирует.


Ответы (1 шт):

Автор решения: vitidev

В чем разница между методами?

string SomeMethod(){...}
Task SomeMethod(){...}

А нет её. Оба метода являются синхронными, просто возвращают в результате разные типы.

Но Task - не магический тип, а самый обыкновенный. Ничем не отличается от любого другого класса. Поэтому просто его наличие не делает синхронный метод асинхронным.

И в синхронных методах исключение прервет выполнение метода (и не вернет результат), а если мы хотим вернуть результат - мы должны создать объект данного типа. В случае со строкой - создать строку, а с Task - создать Task.

Вот тут и пригодится Task.From*.

А вот если мы добавим async

async Task SomeMethod(){...}

то компилятор перепишет метод так, что будет насильно оборачивать результат работы метода в Task. Исключение стоит особняком, а вот с возвратом результата - мы просто не сможем использовать Task.From*, потому что после оборачивания получится Task<Task>, что не совпадает с сигнатурой метода.

Таким образом, выбор "а что лучше использовать" не имеет смысла. В синхронном методе мы вынуждены создавать Task вручную (если он нам нужен), в async методе компилятор не даст нам использовать то, что не совпадает с сигнатурой метода.

→ Ссылка