找不到异步等待的简单方法
Can't find simple way to wait asynchronously
假设我需要执行一些异步操作并且我现在需要结果。如果我使用 C#,我会这样做:
var contents = await File.ReadAllLinesAsync(...);
这里的重要部分是它是非阻塞操作。
我知道 Async.RunSynchronously
,但文档表明它是 阻塞 操作,这意味着它并不比 C# 中的 Task.Result
好。
如果我需要在 F# 中执行相同的操作,我如何在不阻塞的情况下读取文件内容?
如果你想坚持使用任务并行库:
open FSharp.Control.Tasks
let run () = task {
let! contents = File.ReadAllLinesAsync "/path"
return contents
}
这里的task { .. }
类似于C#中的async Task<T>
标记方法,而以!
符号结尾的组合子(例如let!
)可以与[=进行比较15=].
无需深入了解实现细节,主要区别在于 task { .. }
是一个计算表达式,因此它是可插入的 - FSharp.Control.Tasks
命名空间中默认存在一个,但也有其他的有时提供不同功能的实现和库(例如 Ply)。
正如 Bartosz 的回答中所解释的,在 F# 中的 async
方法中使用 await
相当于在计算表达式块中使用 let!
。如果你正在处理 .NET 任务,你可以使用 task { ... }
;如果您正在处理 F# 异步计算,那么您可以使用 async { ... }
.
要使用 async { .. }
,您还可以使用 Async.AwaitTask
:
将任务转换为异步计算
let run () = async {
let! contents = File.ReadAllLinesAsync "/path" |> Async.AwaitTask
return contents
}
如何实际 运行 run ()
功能?首先,没有办法不阻塞地运行计算并等待结果。如果您需要同步代码块中的结果,您只需要阻塞。这与任务相同 - 您可以让它们 运行 并在后台完成,在另一个非阻塞任务中使用它们或阻塞并等待。
如果您不在另一个 async { .. }
街区内,您可以做的两件事是:
// Run the task, do something with the result and
// start the whole operation without blocking
async {
let! result = run ()
printf "%s" result }
|> Async.Start
// Block and wait for the result using RunSynchronously
let result =
run ()
|> Async.RunSynchronously
假设我需要执行一些异步操作并且我现在需要结果。如果我使用 C#,我会这样做:
var contents = await File.ReadAllLinesAsync(...);
这里的重要部分是它是非阻塞操作。
我知道 Async.RunSynchronously
,但文档表明它是 阻塞 操作,这意味着它并不比 C# 中的 Task.Result
好。
如果我需要在 F# 中执行相同的操作,我如何在不阻塞的情况下读取文件内容?
如果你想坚持使用任务并行库:
open FSharp.Control.Tasks
let run () = task {
let! contents = File.ReadAllLinesAsync "/path"
return contents
}
这里的task { .. }
类似于C#中的async Task<T>
标记方法,而以!
符号结尾的组合子(例如let!
)可以与[=进行比较15=].
无需深入了解实现细节,主要区别在于 task { .. }
是一个计算表达式,因此它是可插入的 - FSharp.Control.Tasks
命名空间中默认存在一个,但也有其他的有时提供不同功能的实现和库(例如 Ply)。
正如 Bartosz 的回答中所解释的,在 F# 中的 async
方法中使用 await
相当于在计算表达式块中使用 let!
。如果你正在处理 .NET 任务,你可以使用 task { ... }
;如果您正在处理 F# 异步计算,那么您可以使用 async { ... }
.
要使用 async { .. }
,您还可以使用 Async.AwaitTask
:
let run () = async {
let! contents = File.ReadAllLinesAsync "/path" |> Async.AwaitTask
return contents
}
如何实际 运行 run ()
功能?首先,没有办法不阻塞地运行计算并等待结果。如果您需要同步代码块中的结果,您只需要阻塞。这与任务相同 - 您可以让它们 运行 并在后台完成,在另一个非阻塞任务中使用它们或阻塞并等待。
如果您不在另一个 async { .. }
街区内,您可以做的两件事是:
// Run the task, do something with the result and
// start the whole operation without blocking
async {
let! result = run ()
printf "%s" result }
|> Async.Start
// Block and wait for the result using RunSynchronously
let result =
run ()
|> Async.RunSynchronously