我定义了像这样的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作为参数并等待它?
你的原始定义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.
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)