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