如何在F#中进行简单的等待?
在C#中,我有这样的代码:
Measure = IF(COUNTROWS(ALLSELECTED(Report[Shipment Group])) = 1, "Something which would not filter the units", SELECTEDVALUE(Report[Units], SUM(Report[Units])))
所以我创建了一个让await = ... 到我的F#代码变得与我的C#代码更相似。
我目前的F#代码是:
await collection.InsertOneAsync(DO);
var r = collection.ReplaceOneAsync((fun d -> d.Id = DO.Id), DO)
我想只有一个await(awaits)的定义,但我能做的最好的就是这个,因为在Insere上,type是Task,但在Salva上,type是Task<'T>
如果我只使用等待,我会收到此编译错误:
FS0001类型'Threading.Tasks.Task'与'Threading.Tasks.Task<'a>'
类型不兼容
如果我只使用等待,则会进行编译,但我会从异步任务中丢失返回类型 我想将await和awaits合并为一个
let awaits (t: Threading.Tasks.Task) = t |> Async.AwaitTask |> Async.RunSynchronously
let await (t: Threading.Tasks.Task<'T>) = t |> Async.AwaitTask |> Async.RunSynchronously
let Busca (numero) =
let c = collection.Find(fun d -> d.Numero=numero).ToList()
c
let Insere(DO: DiarioOficial) =
//collection.InsertOneAsync(DO) |> Async.AwaitTask |> Async.RunSynchronously
collection.InsertOneAsync(DO) |> awaits
let Salva (DO: DiarioOficial) =
//let r = collection.ReplaceOneAsync((fun d -> d.Id = DO.Id), DO) |> Async.AwaitTask |> Async.RunSynchronously
let r = collection.ReplaceOneAsync((fun d -> d.Id = DO.Id), DO) |> await
r
我该怎么做?
答案 0 :(得分:3)
在F#中,我们倾向于使用另一种语法。例如描述了在这里:https://fsharpforfunandprofit.com/posts/concurrency-async-and-parallel/.
使用C#Tasks的想法是将它们“转换”为异步Async.Await<'T>
你可以采取另一种方式,但这是最直接的。
答案 1 :(得分:2)
在F#和C#中编写异步代码有两个部分。
您需要将方法或代码块标记为异步。在C#中,这是使用async
关键字完成的。 F#等价物是使用async { ... }
块(这是一个表达式,但除此之外,它是相似的)。
在async
方法或async { .. }
块中,您可以进行非阻止调用。在C#中,这是使用await
完成的,在F#中使用let!
完成。请注意,这不仅仅是一个函数调用 - 编译器以特殊方式处理它。
F#也使用Async<T>
类型而不是Task<T>
,但这些很容易转换 - 例如使用Async.AwaitTask
。所以,你可能想要这样的东西:
let myAsyncFunction () = async {
let! _ = collection.InsertOneAsync(DO) |> Async.AwaitTask
let r = collection.ReplaceOneAsync((fun d -> d.Id = DO.Id), DO)
// More code goes here
}
我使用let!
来表达这个想法,但是如果你有一个返回unit
的异步操作,你也可以使用do!
do! collection.InsertOneAsync(DO) |> Async.AwaitTask