共用方式為


MailboxProcessor.TryScan<'Msg,'T> 方法 (F#)

依照收到的順序查詢訊息以掃描訊息,直到所提供的函式傳回 Some 值。 其他訊息仍在佇列中。

**命名空間/模組路徑:**Microsoft.FSharp.Control

組件:FSharp.Core (在 FSharp.Core.dll 中)

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

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

參數

  • scanner
    型別:'Msg -> Async<'T> option

    函式,在要略過訊息時傳回 None,而在要處理訊息並從佇列中移除時傳回 Some。

  • timeout
    型別:int

    選擇性逾時 (以毫秒為單位)。 預設為 -1,對應至 Infinite。

傳回值

非同步計算 (Async 物件), scanner 建置讀取訊息。

備註

如果超過逾時期間, None 傳回。 這個方法要在代理程式的主體中使用。 針對每個代理程式,最多可以有一個現用並行閱讀器,所以 Receive, TryReceive, ScanTryScan 的使用中呼叫不能超過一個。 scanner函式的主體在執行期間遭被鎖定,但在執行非同步工作流之前已解除鎖定。

範例

下列程式碼範例顯示如何使用 TryScan 方法。 這個範例是工作提交代理程式。 有三個代理程式:啟動每個工作的人員呼叫 runAgent ,表示所有執行作業的另一個名為的 inprogressAgent ,如此一來,表示告知的每一次呼叫 completeAgent 工作完成。 TryScan 用來 cancelJob 函式找到這個工作取消,或是失敗,如果找不到符合的工作。

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

下列為範例工作階段。

  
  
  
  
  
  
  
  
  

平台

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

版本資訊

F# 核心程式庫版本

支援版本:2.0, 4.0,可攜式執行檔 (PE)。

請參閱

參考

Control.MailboxProcessor<'Msg> 類別 (F#)

Microsoft.FSharp.Control 命名空間 (F#)