[英]F# issue with async workflow and try/with
我正在努力整理一個簡單的功能。
考慮以下定義:
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語言開發的庫。
(我為了這個例子創建了這段代碼)
基本上,我想在存儲庫服務中保存數據,然后將數據保存在通知服務中。 但是如果第二個操作失敗,並且包含異常,我想回滾存儲庫中的操作。 然后有兩種情況我想要調用回滾操作,第一種是if 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 = ...
上遇到了編譯器錯誤let! nr = ...
let! nr = ...
說: 此構造只能在計算表達式中使用
這是正確的方法嗎?
問題是當你在計算表達式中使用let v = e
時,表達式e
是一個普通的表達式,不能包含其他異步結構。 這正是這里發生的事情:
let notifResult =
try
let! nr = Async.AwaitTask <| notification.SaveAsync(entities)
nr
with _-> false
您可以將其轉換為嵌套的async
塊:
let! notifResult = async {
try
let! nr = Async.AwaitTask <| notification.SaveAsync(entities)
return nr
with _-> return false }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.