vto*_*ola 3 f# asynchronous 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>
Run Code Online (Sandbox Code Playgroud)
这Task<T>
是因为它们是用其他.NET语言开发的库.
(我为了这个例子创建了这段代码)
基本上,我想在存储库服务中保存数据,然后将数据保存在通知服务中.但是如果第二个操作失败,并且包含异常,我想回滚存储库中的操作.然后有两种情况我想要调用回滚操作,第一种if notification.SaveAsync
返回false,第二种if抛出异常.当然,我想编写一次调用回滚,但我找不到方法.
这是我尝试过的:
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
Run Code Online (Sandbox Code Playgroud)
但不幸的是我得到了一个编译错误let! nr = ...
:这个结构只能在计算表达式中使用
这是正确的方法吗?
问题是,当您let v = e
在计算表达式中使用时,表达式e
是一个普通表达式,不能包含其他异步结构.这正是这里发生的事情:
let notifResult =
try
let! nr = Async.AwaitTask <| notification.SaveAsync(entities)
nr
with _-> false
Run Code Online (Sandbox Code Playgroud)
您可以将其转换为嵌套async
块:
let! notifResult = async {
try
let! nr = Async.AwaitTask <| notification.SaveAsync(entities)
return nr
with _-> return false }
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
261 次 |
最近记录: |