#asynchronous #f# #task
#асинхронный #f# #задача
Вопрос:
Я пишу приложение на F # и хочу как можно больше избавиться от явных ссылок на task . Является ли следующее эквивалентным Task.Run
или я что-то упускаю?
[<AutoOpen>]
module Async =
let inline runInThreadPool backgroundTask = async {
let originalContext = System.Threading.SynchronizationContext.Current
do! Async.SwitchToThreadPool()
let! result = backgroundTask()
do! Async.SwitchToContext originalContext
return result}
Пример использования (непроверенный):
async { // starts on the UI thread
let! result = Async.runInThreadPool(fun _ -> async {
let mutable sum= 0
for i in 1..10000 do
sum <- sum 1
return sum })
//do something with the result in the UI
} |> Async.StartImmediate
Комментарии:
1. Я не понимаю, чего это должно достичь. С чем это связано
Task
?Task.Run
эквивалентноAsync.Start
.2. Используете ли вы API, которые работают с задачами? Если это так, вы можете легко преобразовать их в
Async
s с помощьюAsync.AwaitTask
. В любом случае, я не вижу смысла в написании замены дляAsync.Start
.3. А, понял. Я хочу выполнить некоторую фоновую обработку и в настоящее время использую
Task.Run
withAsync.AwaitTask
. Я хочу заменитьTask.Run
s наAsync
, поэтому я хочу знать, эквивалентен ли опубликованный код (т. Е. Выполняется в фоновом потоке, но запускает продолжение в исходном потоке).4. Я не уверен в поведении потоков, но просто сравниваю документы для
Task.Run
иAsync.Start
, кажется, они одинаковы.5.
async { }
Блок уже выполняется в пуле потоков. Вы можете просто изменитьlet! result = Async.runInThreadPool(fun _ -> async {
наlet! result = async {
.
Ответ №1:
Как указал @Daniel, это лучше достигается с помощью Async.StartChild
такого:
[<AutoOpen>]
module Async =
let inline runInThreadPool backgroundTask = async {
let! result = backgroundTask() |> Async.StartChild
return! result}