F# - 编写一个接受非泛型和泛型参数的函数

0xa*_*yan 3 f#

我定义了像这样的await函数:

let await (task : Task<'a>) =
    task |> Async.AwaitTask |> Async.RunSynchronously
Run Code Online (Sandbox Code Playgroud)

和这样的两个任务:

let stringTask = new Task<string>(fun () -> "something")

let unitTask = new Task(fun () -> printf "something")
Run Code Online (Sandbox Code Playgroud)

像这样打电话给他们:

let stringResult = await stringTask
await unitTask
Run Code Online (Sandbox Code Playgroud)

但第二个不是通用的,我无法调用await它,因此我编辑了函数参数,如下所示:

let await (task : Task) =
    task |> Async.AwaitTask |> Async.RunSynchronously
Run Code Online (Sandbox Code Playgroud)

问题是现在await stringTask正在返回unit而不是string.

我应该如何编写await函数来接受Task <'a>和Task作为参数并等待它?

AMi*_*res 5

你的原始定义await很好.

问题在于unitTask它不是通用的.使其与通用方式相同stringTask:

let unitTask = new Task<unit>(fun () -> printf "something")
Run Code Online (Sandbox Code Playgroud)

如果要同时处理泛型Task<'a>和非泛型Task,则有2个选项.

创建2个await功能(功能方式):

let await     (task : Task<'a>) = task |> Async.AwaitTask |> Async.RunSynchronously
let awaitUnit (task : Task    ) = task |> Async.AwaitTask |> Async.RunSynchronously
Run Code Online (Sandbox Code Playgroud)

或者Await在类型上创建2个成员Task(OO方式):

type Task with 
    static member Await (task : Task    ) = task |> Async.AwaitTask |> Async.RunSynchronously
    static member Await (task : Task<'a>) = task |> Async.AwaitTask |> Async.RunSynchronously
Run Code Online (Sandbox Code Playgroud)

按惯例,成员使用Pascal案例,所以我用Await而不是await.

在打电话task.Start()之前记得打电话await.


Hon*_*tan 5

Async.AwaitTask已经有重载既Task<'a>Task,所以除非你真的需要一个辅助功能,可以直接使用它:

let stringResult = Async.AwaitTask stringTask |> Async.RunSynchronously
Async.AwaitTask unitTask |> Async.RunSynchronously
Run Code Online (Sandbox Code Playgroud)

如果这是您的实际代码并且您确实需要阻止线程等待这些结果,您还可以直接使用Task API来保存任务 - >异步转换开销:

let stringResult = stringTask.Result
unitTask.Wait()
Run Code Online (Sandbox Code Playgroud)