Это не решение вашего вопроса о направлении, но именно так я бы построил что-то для этого:
Первый - создать таблицу событий со столбцами для идентификатора транзакции, действия и статуса.
Пользователь будет взаимодействовать с кнопкой для сохранения данных.
Страница вызывает ваш контроллер и получает идентификатор транзакции. Это возвращается на вашу страницу вызова.
Внутренне контроллер затем вызывает отдельные методы для сохранения данных и отправки электронных писем. Он передает назначенный идентификатор транзакции каждому методу.
Когда каждый метод завершается успешно, он обновляет таблицу событий с идентификатором транзакции, состоянием и связанным действием.
Вернувшись на вызывающую страницу, теперь с идентификатором транзакции, ваша страница начинает опросить другой метод, чтобы проверить таблицу событий на предмет заданного действия и статуса. Он может проверять каждую секунду, каждые пять секунд, что у вас.
Когда таблица событий обновляется, вы можете обновить пользовательский интерфейс на странице, чтобы указать, что действие произошло.
Вы можете использовать таблицу событий для множества вещей, помимо этой единственной функциональности. Если не считать Signal R или Meteor или иметь полнофункциональный продукт для обработки событий в очереди, это должно помочь вам.
Таким образом, пользователь нажимает одну кнопку, и страница обновляется по мере выполнения действий.