簡體   English   中英

如何在F#中實現返回Task(非泛型)的方法的接口

[英]How to implement interface having method returning Task (non-generic) in F#

說我有接口:

interface IProductRepository
{
    Task SaveProduct(Product p);
}

以前由C#類實現:

class CSharpProductRepository : IProductRepository
{
    public Task SaveProduct(Product p)
    {
        _db.Products.Add(p);
        return _db.SaveChangesAsync();
    }
}

現在我想在F#中實現相同的功能:

type FSharpProductRepository =
    interface IProductRepository with
        member this.SaveProduct(p : Product) : Task = this.SaveProduct(p) // error 1

    member this.SaveProduct(p : Product) = async {
        db.Products.Add(p)
        return db.SaveChangesAsync() |> Async.AwaitTask // error 2
    }

但是得到一個錯誤(1):

該表達式應該具有類型Task,但這里的類型為Async <'a>

(2):

類型約束不匹配。 類型Task與類型Task <'a>不兼容

鑒於Task<'a>Task的子類型,你可以像這樣做:

open System.Threading.Tasks

// stubs since I don't know what the actual code looks like
type Product = class end

type IProductRepository = 
    abstract SaveProduct: product: Product -> Task

type Db = 
    abstract Products: System.Collections.Generic.ICollection<Product>
    abstract SaveProductAsync: product: Product -> Task<int>

type Repository(db: Db) = 
    interface IProductRepository with
        member this.SaveProduct(p: Product) = 
            db.Products.Add(p)
            upcast db.SaveProductAsync(p)

你需要使用Async.StartAsTask啟動async工作流但遺憾的是這不起作用,因為這將需要一個通用任務Task<'a> :( - 所以我認為你必須使用AwaitWaitHandle方法與任務AsyncWaitHanlde

type FSharpProductRepository =
    interface IProductRepository with
        member this.SaveProduct(p : Product) : Task = 
           this.SaveProduct(p)

    member this.SaveProduct(p : Product) = 
       async {
          db.Product.Add(p)
          let task = db.SaveChangesAsync() 
          let! _ = Async.AwaitWaitHandle (task :> IAsyncResult).AsyncWaitHandle
          return ()
       } |> Async.StartAsTask :> _

直接返回任務:

直接返回任務更有意義,就像上面的代碼(只是鏡像C#實現)一樣,它只啟動一個線程,啟動另一個線程( db.SaveChanges() )等待保存更改並返回..對我來說似乎有些過分。

這只有IMO才有意義,如果你繼續使用async -Workflow(刪除Async.StartAsTask - 或者你將使用AwaitWaitHandle的重載,它會在幾毫秒后超時)。

    member this.SaveProduct(p : Product) = 
      db.Product.Add(p)
      db.SaveChangesAsync()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM