繁体   English   中英

F#问题与异步工作流和try / with

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM