簡體   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