2014-11-19 4 views
1

스케쥴러를 도입하여 Async.Parallel을 제한/제한 할 수있는 방법이 있습니까? Seq of Async < 'a>를 병렬로 실행하려고하지만 특정 시간 제한을 초과하고 싶지는 않습니다.Async.Parallel로 예약하기

각 비동기 < 'a>가 검사하는 공유 가능 변수를 사용할 수 있지만 가능한 경우이를 피하고 싶습니다.

답변

5

커버 아래에서 Async.Parallel 작업은 표준 .NET 스레드 풀을 사용합니다. 따라서 스레드 풀을 구성 할 수는 있지만 스레드 풀에서 스레드를 차단하면 안됩니다.

약간의 조절을 구현하고 싶다면 이것을 위해 F # 에이전트를 만들 수 있습니다.

// We can ask the agent to enqueue a new work item; 
// and the agent sends itself a completed notification 
type ThrottlingMessage = 
    | Enqueue of Async<unit> 
    | Completed 

let throttlingAgent limit = MailboxProcessor.Start(fun inbox -> async { 
    // The agent body is not executing in parallel, 
    // so we can safely use mutable queue & counter 
    let queue = System.Collections.Generic.Queue<_>() 
    let running = ref 0 
    while true do 
    // Enqueue new work items or decrement the counter 
    // of how many tasks are running in the background 
    let! msg = inbox.Receive() 
    match msg with 
    | Completed -> decr running 
    | Enqueue w -> queue.Enqueue(w) 
    // If we have less than limit & there is some work to 
    // do, then start the work in the background! 
    while running.Value < limit && queue.Count > 0 do 
     let work = queue.Dequeue() 
     incr running 
     do! 
     // When the work completes, send 'Completed' 
     // back to the agent to free a slot 
     async { do! work 
       inbox.Post(Completed) } 
     |> Async.StartChild 
     |> Async.Ignore }) 

것은이를 사용하려면, 당신은을 만들 수 있습니다 : 그것은 아마 (이 목적을 위해) 변경 가능한 변수를 사용하는 것보다 더 많은 코드이지만, 그것은 당신에게 좋은 추상화를 제공 - 에이전트는 당신에게 동시성을 조정하는 매우 간단한 방법을 제공 오히려 Completed 통지를하는 것보다 (당신을하지만 방향을 표시해야합니다 -

let w = throttlingAgent 5 
for i in 0 .. 20 do 
    async { printfn "Starting %d" i 
      do! Async.Sleep(1000) 
      printfn "Done %d" i } 
    |> Enqueue 
    |> w.Post 

이것은 당신이 가지고있는 것보다 조금 다른 문제를 해결한다 : 지정된 한계 에이전트 다음 Enqueue를 호출하여 작업 항목을 추가하는 방법 아마도 async을 백그라운드에서 보내고 싶을 것입니다. 매 시간마다 "토큰 수").

+0

이렇게하면 도움이됩니다. 토마스에게 감사드립니다. 나는 MailBoxProcessors를 사용하지 않았으며, 나를 소개해 줘서 고마워. – WiseGuyEh

+0

당신을 환영합니다! 좋은 시작점은 http://www.developerfusion.com/article/139804/an-introduction-to-f-agents/ 및 http://www.developerfusion.com/article/140677/writing-concurrent- applications-f-agents/ –

+0

다시 한 번, 감사합니다. 나는 그들을 확실히 확인해 보겠습니다. – WiseGuyEh