Udostępnij za pośrednictwem


MailboxProcessor.TryScan<'Msg,'T> — Metoda (F#)

Skanowanie w poszukiwaniu wiadomości przeglądając wiadomości w kolejności przyjazdu dopóki podana funkcja nie zwróci Some wartości.Inne wiadomości pozostają w kolejce.

Przestrzeń nazw/Ścieżka modułu: Microsoft.FSharp.Control

Zestaw: FSharp.Core (w FSharp.Core.dll)

// Signature:
member this.TryScan : ('Msg -> Async<'T> option) * ?int -> Async<'T option>

// Usage:
mailboxProcessor.TryScan (scanner)
mailboxProcessor.TryScan (scanner, timeout = timeout)

Parametry

  • scanner
    Wpisz: 'Msg -> Async<'T> option

    Funkcja, która zwraca None, jeśli wiadomość ma zostać pominięta lub Some, jeśli wiadomość ma zostać przetworzona i usunięta z kolejki.

  • timeout
    Wpisz: int

    Opcjonalny limit czasu zapisu w milisekundach.Ustaw domyślnie na -1, co odnosi się do Infinite.

Wartość zwracana

Asynchroniczne obliczenie (obiekt Async ), który scanner rozbudowuje odczytany komunikat.

Uwagi

Jeśli zostanie przekroczony limit czasu, None jest zwracany.Ta metoda jest do użytku w ramach organu agenta.Dla każdego agenta, co najwyżej jeden równoczesny czytnik może być aktywny, więc nie więcej niż jedno równoczesne wywołanie do Uzyskaj, TryReceive, Skan lub TryScan może być aktywne.Ciało scanner funkcji jest zablokowane podczas jego realizacji, ale blokada jest zwalniana przed wykonaniem asynchronicznego przepływu pracy.

Przykład

Poniższy kod ilustruje sposób używania metody TryScan.W tym przykładzie jest agentem przesyłania zadania.Istnieją trzy czynniki: jeden o nazwie runAgent , rozpoczyna każde zadanie, innym o nazwie inprogressAgent reprezentuje wszystkie uruchomione zadania i jeden o nazwie completeAgent reprezentuje powiadomienie, że zadanie jest zakończone.TryScan jest używany w cancelJob funkcji szukania pracy, aby anulować lub się nie powieść, jeśli nie ma żadnego pasującego zadania.

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

Poniżej znajduje się przykład sesji.

              

Platformy

Windows 8, Windows 7, Windows Server 2012, Windows Server 2008 R2

Informacje o wersji

Wersje podstawowe biblioteki języka F#

Obsługiwane przez: 2.0, 4.0, przenośne

Zobacz też

Informacje

Control.MailboxProcessor<'Msg> — Klasa (F#)

Microsoft.FSharp.Control — Przestrzeń nazw (F#)