说我有界面:
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):
类型约束不匹配。类型任务与类型任务<' a>
不兼容
答案 0 :(得分:5)
鉴于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)
答案 1 :(得分:4)
您需要使用async
启动Async.StartAsTask
工作流程,但遗憾的是,这不起作用,因为这需要通用任务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()
)等待保存更改并返回......对我来说似乎有点过分了。
只有当您继续使用async
- 工作流程(删除Async.StartAsTask
- 或者您将使用AwaitWaitHandle
的重载时,IMO才会有意义
会在几毫秒后超时。)
member this.SaveProduct(p : Product) =
db.Product.Add(p)
db.SaveChangesAsync()