Quelles sont les différentes techniques que vous pouvez utiliser pour créer des instances d'ASYNC <'T> en F #?
Je vois qu'il existe un certain nombre de méthodes d'extension pour Web Client / Demande et flux de fichiers, mais si je veux écrire mon propre fournisseur de calculs ASYNC, comment irai-i d'écrire ces Je sais que vous pouvez utiliser un délégué de la même signature pour envelopper la fonction d'origine, puis utiliser mais cela ressent un peu forcé et il ne semble pas Soyez la «F # Way» car vous devez utiliser des délégués définis dans C # ou VB (dont il y a beaucoup de Est-ce que quelqu'un a une liste des différentes façons que vous puissiez écrire une asynchrone version d'une fonction synchrone dans F #? P> Merci beaucoup d'avance! p> p> asyncdosomething code> versions de mon
Dosomething Synchrone code> Fonctions? P>
async.fombeginend code > sur le
begininvoke code> et
endinvoke code> méthodes: p>
system.action code> et
system.func code> variantes au choix de Cours) parce que f # délégués ne prend pas en charge le
beginInvoke code> et
endinvoke code> méthodes. p>
3 Réponses :
du docs pour Voici un peu de code pour démontrer ce point. P > async code>
, tous les AWAITEXXX code> et
fromxxx code> méthodes. Mais le moyen le plus courant consiste à utiliser workflows asynchrone . Cependant, comme Mauricio a commenté, l'emballage du code arbitraire avec
async {} code> n'est pas toujours bénéfique.
Mise à jour h3>
open System.IO
let BUF_SIZE = 1 <<< 16 //64KB
let readFile f (stream:Stream) =
let buf = Array.zeroCreate BUF_SIZE
let rec read p =
async {
let! n = f stream buf
match n with
| 0 -> ()
| _ -> return! read (p + n)
}
read 0
let fakeAsyncReadFile s = readFile (fun stream buf ->
async { return stream.Read(buf, 0, buf.Length) }) s
let realAsyncReadFile s = readFile (fun stream buf ->
stream.AsyncRead(buf, 0, buf.Length)) s
let files = [@"C:\big_file_1"; @"C:\big_file_2"]
let readWith f =
let streams = Seq.map File.OpenRead files
try Seq.map f streams |> Async.Parallel |> Async.RunSynchronously |> ignore
finally streams |> Seq.iter (fun s -> s.Close())
readWith fakeAsyncReadFile //Real: 00:00:34.190, CPU: 00:00:03.166, GC gen0: 4, gen1: 2, gen2: 1
readWith realAsyncReadFile //Real: 00:00:05.101, CPU: 00:00:16.957, GC gen0: 31, gen1: 1, gen2: 0
Pouvez-vous élaborer sur l'utilisation d'ASYNC {}? Le let! La liaison nécessite une instance d'Async <'T> sur le côté droit de l'expression, et c'est la création de ces cas d'asynchronisation <' T> qui m'intéresse.
Awahitvent et AwaitTask peut être utile si vous avez une tâche ou un événement à la main, je suppose.
Alors quelque chose comme ça? Laissez Delasync2 = async {retour 42} printfn "résultat était% d" <| ASYNC.RUNSYNYNYNYNYNCYNC2
Blog de Don Syme A > a quelques exemples.
Vous pouvez obtenir un bon kilométrage d'async.fromcontinuations. Cette fonction vous permet de définir une asynchronisation des fonctions de continuation. Si vous regardez la définition de l'asyncdownloadstring de WebClient, vous le verrez en utilisation. P>
Et vous pouvez écrire comme ceci: et l'utiliser comme p>
Faire une asynchronisation d'une synchronisation implicite n'a pas beaucoup de sens IMHO.
Vrai, c'est surtout utile lorsque vous devez faire du travail IO (ASYNC vous permet de libérer un thread autrement bloqué dans la version de synchronisation), qui sont déjà couverts par les méthodes de vulgarisation communes de F #, mais je suis juste intéressé par «Comment «Vous allez faire ça. Peut-être qu'un jour, vous rencontrerez une méthode qui effectue des travaux io mais ne vient pas avec une paire de début / de fin, par exemple.