Зачем нужен пустой делегат Action

1,00
р.
Изучая лямбда выражения наткнулся на делегаты Action и Func. Зачем нужен второй я понял, хотя бы для :
Func summ = (x, y) => x + y Console.WriteLine(summ(10,20))
Но для чего нужен пустой Action непонятно.
Приведите простенький пример зачем он может понадобиться ? И почему нельзя поставить void в Func и получить тот же самый Action вида Func например?

Ответ
Существует два мира - мир чистого функционального программирования и реальный.
В чистом мире чистого функционального программирования не существует изменяемого состояния и не существует операторов (statements), а все является выражением. В этом идеальном мире у функций нет побочных эффектов, а любая конструкция в языке программирования является выражением (т.е. возвращает результат).
Но в реальном мире - все по другому.
В реальном мире, а особенно в мире C#, есть побочные эффекты и есть замечательный тип Void, который является необычным типом, не совместимым с другими. В этом мире действие (Action) не может быть выражено через функцию (Func), просто потому, что Func запрещен, а тип Unit (аналогичный типу Void, но приводимый к обобщенному типу T) отсутствует. Если бы это было не так, то следующий код был бы валиден:
Func fun = n => System.Console.WriteLine(n)
Это не значит, что данное правило универсально для всех языков реального мира, и даже для мира .NET, но для C# - это так. Тот же F# (язык более близкий к математическому миру) имеет тип Unit и умеет автоматически конвертировать .NET-ый Void в Unit, что делает приведенный код валидным.
TL DR Func запрещен по историческим причинам (что жалко), поскольку очень часто приходится городить конвертер, который преобразует Func, в Action и отбросит результат.
Если же говорить о реальные сценарии, то с применимостью типов Action проблем никаких.
Parallel.For/Parallel.ForEach: Parallel.For(0, list.Count, n => Console.WriteLine(list[n]) Похоже с предыдущим - ActionBlock и действие, которое должно выполняться разумным числом потоков. Task и действие, которое должно быть выполнено асинхронно: var task = Task.Run(() => SomeOperation()) Всяческие коллбеки для логгирования и прочих операций, которые ничего не возвращают.
В общем, наличие и популярность void-return функций определяет применимость Action. По хорошему, нам стоит стараться свести побочные эффекты к разумному минимуму, но в реальном мире, этот минимум никогда не станет 0.