У меня болит голова, пытаясь собрать простую функциональность.F # Проблема с асинхронным рабочим процессом и попробуйте/с
Рассмотрим следующие определения:
type Entity = {Id:int;Data:string}
type IRepository =
abstract member SaveAsync: array<Entity> -> Task<bool>
abstract member RollBackAsync: array<Entity> -> Task<bool>
type INotification =
abstract member SaveAsync: array<Entity> -> Task<bool>
Использование Task<T>
, потому что они являются библиотеки, разработанные в других языках .NET.
(я создал этот код ради примера)
В принципе, я хочу, чтобы сохранить данные в службе хранилища, а затем сохранить данные в службе уведомления. Но если эта вторая операция завершается с ошибкой и включает исключения, я хочу отменить операцию в репозитории. Тогда есть две ситуации, когда я хотел бы вызвать операцию отката, первый, если notification.SaveAsync
возвращает false, а второй, если он выдает исключение. И, конечно, я хотел бы запрограммировать этот призыв к откату один раз, но я не могу найти способ.
Это то, что я пробовал:
type Controller(repository:IRepository, notification:INotification) =
let saveEntities entities:Async<bool> = async{
let! repoResult = Async.AwaitTask <| repository.SaveAsync(entities)
if(not repoResult) then
return false
else
let notifResult =
try
let! nr = Async.AwaitTask <| notification.SaveAsync(entities)
nr
with
| _-> false
if(not notifResult) then
let forget = Async.AwaitTask <| repository.RollBackAsync(entities)
return false
else
return true
}
member self.SaveEntitiesAsync(entities:array<Entity>) =
Async.StartAsTask <| saveEntities entities
Но, к сожалению, я получаю сообщение об ошибке на let! nr = ...
говоря: Эта конструкция может быть использована только в расчетных выражениях
Какой бы правильный путь делать это?
Что интересно, я не заметил, что вы можете вложить их. Благодаря! – vtortola