Это эквивалентно Task.Run?

#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 with Async.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}