MailboxProcessor.Scan<'Msg,'T>, méthode (F#)
Recherche un message en consultant les messages dans l'ordre d'arrivée jusqu'à ce qu'une fonction fournie retourne une valeur Some. Les autres messages demeurent dans la file d'attente.
Espace de noms/Chemin du module : Microsoft.FSharp.Control
Assembly : FSharp.Core (in FSharp.Core.dll)
// Signature:
member this.Scan : ('Msg -> Async<'T> option) * ?int -> Async<'T>
// Usage:
mailboxProcessor.Scan (scanner)
mailboxProcessor.Scan (scanner, timeout = timeout)
Paramètres
scanner
Type : 'Msg -> Async<'T> optionFonction qui retourne None si le message doit être ignoré ou Some si le message doit être traité et supprimé de la file d'attente.
timeout
Type : intDélai d'attente facultatif en millisecondes. -1 est la valeur par défaut, qui correspond à Infinite.
Exceptions
Exception |
Condition |
---|---|
Levée lorsque le délai d'attente est dépassé. |
Valeur de retour
Un calcul asynchrone (objet Async) qui scanner a créé à partir du message lu.
Notes
Cette méthode doit être utilisée dans le corps de l'agent. Pour chaque agent, un lecteur simultané au maximum pouvant être actif, un seul appel simultané à Receive, TryReceive, Scan ou TryScan peut être actif. Le corps de la fonction scanner est verrouillé pendant son exécution, mais le verrou est libéré avant l'exécution du flux de travail asynchrone.
Exemple
L'exemple suivant illustre l'utilisation de la méthode Scan. Dans ce code, les agents de processeur de boîte aux lettres gèrent une série de travaux simulés qui exécutent et calculent un résultat.
open System
open System.Threading
let random = System.Random()
// Generates mock jobs by using Async.Sleep.
let createJob(id:int, source:CancellationTokenSource) =
let job = async {
// Let the time be a random number between 1 and 10000.
// The mock computed result is a floating point value.
let time = random.Next(10000)
let result = random.NextDouble()
let count = ref 1
while (!count <= 100 && not source.IsCancellationRequested) do
do! Async.Sleep(time / 100)
count := !count + 1
return result
}
id, job, source
type Result = double
// A Job consists of a job ID and a computation that produces a single result.
type Job = int * Async<Result> * CancellationTokenSource
type Message = int * Result
let context = System.Threading.SynchronizationContext.Current
// This agent processes when jobs are completed.
let completeAgent = MailboxProcessor<Message>.Start(fun inbox ->
let rec loop n =
async {
let! (id, result) = inbox.Receive()
printfn "The result of job #%d is %f" id result
do! loop (n + 1)
}
loop (0))
// inprogressAgent maintains a queue of in-progress jobs that can be
// scanned to remove canceled jobs. It never runs its processor function,
// so we set it to do nothing.
let inprogressAgent = new MailboxProcessor<Job>(fun _ -> async { () })
// This agent starts each job in the order in which it is received.
let runAgent = MailboxProcessor<Job>.Start(fun inbox ->
let rec loop n =
async {
let! (id, job, source) = inbox.Receive()
printfn "Starting job #%d" id
// Post to the in-progress queue.
inprogressAgent.Post(id, job, source)
// Start the job.
Async.StartWithContinuations(job,
(fun result -> completeAgent.Post(id, result)),
(fun _ -> ()),
(fun cancelException -> printfn "Canceled job #%d" id),
source.Token)
do! loop (n + 1)
}
loop (0))
for id in 1 .. 10 do
let source = new CancellationTokenSource()
runAgent.Post(createJob(id, source))
let cancelJob(cancelId) =
Async.RunSynchronously(
inprogressAgent.Scan(fun (jobId, result, source) ->
let action =
async {
printfn "Canceling job #%d" cancelId
source.Cancel()
}
// Return Some(async) if the job ID matches.
if (jobId = cancelId) then
Some(action)
else
None))
printfn "Specify a job by number to cancel it, then press Enter."
let mutable finished = false
while not finished do
let input = System.Console.ReadLine()
let a = ref 0
if (Int32.TryParse(input, a) = true) then
cancelJob(!a)
else
printfn "Terminating."
finished <- true
Un exemple de session suit.
Plateformes
Windows 8, Windows 7, Windows Server 2012, Windows Server 2008 R2
Informations de version
Versions de la bibliothèque principale F#
Prise en charge dans : 2,0, 4,0, Portable