Metodo MailboxProcessor.TryScan<'Msg,'T> (F#)
Cerca un messaggio analizzando i messaggi in ordine di arrivo finché una funzione fornita non restituisce un valore Some. Gli altri messaggi rimangono nella coda.
Percorso di spazio dei nomi/modulo: Microsoft.FSharp.Control
Assembly: FSharp.Core (in FSharp.Core.dll)
// Signature:
member this.TryScan : ('Msg -> Async<'T> option) * ?int -> Async<'T option>
// Usage:
mailboxProcessor.TryScan (scanner)
mailboxProcessor.TryScan (scanner, timeout = timeout)
Parametri
scanner
Tipo: 'Msg -> Async<'T> optionFunzione che restituisce None se il messaggio deve essere ignorato oppure Some se il messaggio deve essere elaborato e rimosso dalla coda.
timeout
Tipo: intTimeout facoltativo in millisecondi. L'impostazione predefinita è -1, che corrisponde a Infinite.
Valore restituito
Calcolo asincrono (oggetto Async) che scanner compilato al di fuori del messaggio di lettura.
Note
Se un periodo di timeout viene superato, viene restituito None. Questo metodo deve essere utilizzato all'interno del corpo dell'agente. Per ogni agente, può essere attivo al massimo un lettore simultaneo, pertanto non può essere attiva più di una chiamata simultanea ai metodi Receive, TryReceive, Scan o TryScan. Il corpo della funzione scanner viene bloccato durante l'esecuzione, ma il blocco viene rilasciato prima dell'esecuzione del flusso di lavoro asincrono.
Esempio
Nell'esempio di codice riportato di seguito viene illustrato come utilizzare il metodo TryScan. Questo esempio è un agente per l'invio di processi. Sono disponibili tre agenti: uno denominato runAgent che avvia ogni processo, un altro denominato inprogressAgent che rappresenta tutti i processi in esecuzione ed uno chiamato completeAgent che notifica quando un processo viene completato. TryScan viene utilizzato nella funzione cancelJob per cercare un processo da annullare o fallisce se non esiste alcun processo corrispondente.
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, a computation that produces a single result,
// and a cancellation token source object that can be used to cancel the job.
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.TryScan((fun (jobId, result, source) ->
let action =
async {
printfn "Canceling job #%d" cancelId
source.Cancel()
return cancelId
}
// Return Some(async) if the job ID matches.
if (jobId = cancelId) then
Some(action)
else
None), 1000))
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
match cancelJob(!a) with
| Some id -> printfn "A job was canceled: job #%d" id
| None -> printfn "Job not found."
else
printfn "Terminating."
finished <- true
Di seguito viene riportata una sessione di esempio.
Piattaforme
Windows 8, Windows 7, Windows Server 2012, Windows Server 2008 R2
Informazioni sulla versione
Versioni della libreria di base di F#
Supportato in: 2.0, 4.0, portabile