繁体   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