Вычислительные выражения F# и параллельная библиотека задач
В последнее время я много работал с F#, а недавно написал небольшое приложение MVC с веб-проектом на C# и библиотекой классов F#, последняя из которых содержала основную часть кода.
Я хотел использовать функцию асинхронных контроллеров более поздних версий MVC, где вы можете вернуть Task<ActionResult>
, Я писал свой код с использованием выражений асинхронных вычислений F#, но меня очень раздражало необходимость постоянно преобразовывать из Async<'T> в Task<' T>, используя Async.AwaitTask
а также StartAsTask
,
Так как в то время я изучал выражения вычислений, я подумал: "Должен быть способ использовать выражения вычислений с заданиями, а также с Async, чтобы обеспечить лучшее взаимодействие F#/C#", поэтому я решил:
type TaskBuilder () =
member this.ReturnFrom task = task
member this.Return value = Task.FromResult value
member this.Bind (task : Task<'a>, continuation: 'a -> Task<'b>) =
task.ContinueWith(fun (t : _ Task) ->
(t.Result |> continuation).Result)
member this.Zero () = Task.FromResult ()
Это похоже на работу; запустив следующий код:
let task = TaskBuilder()
task {
let! data = (new WebClient()).DownloadStringTaskAsync(Uri "http://www.google.com")
printfn "Downloaded from Google: %A" (data.Length)
}
|> ignore
task {
let! data = (new WebClient()).DownloadStringTaskAsync(Uri "http://www.bing.com")
printfn "Downloaded from Bing: %A" (data.Length)
}
|> ignore
printfn "Hello world"
дает результат:
Here
Downloaded from Bing: 39121
Downloaded from Google: 46005
Это создает видимость асинхронности, и вы получите правильный тип, если вернетесь из выражения для вычисления, поэтому я осторожно отмечаю это как успешный.
Что вызывает у меня подозрение, так это то, что я не смог найти примеров того, как другие люди пытаются это сделать, поэтому я был бы признателен за внешнюю перспективу
- Это сработало?
- Это хорошая идея в первую очередь?