Почему этот код F# не генерирует ожидаемый результат при использовании с MailboxProcessor?

Я просматривал одну из записей блога Дона Сайма Асинхронные и параллельные шаблоны проектирования в F#: агенты. Однако следующий, казалось бы, очень простой код не генерировал ожидаемых результатов.

type Agent<'T> = MailboxProcessor<'T>

let agent =
   Agent.Start(fun inbox ->
     async { while true do
               let! msg = inbox.Receive()
               printfn "got message '%s'" msg } )

for i in 1 .. 10000 do
   agent.Post (sprintf "message %d" i)

Вместо ожидаемых 10 000 сообщений я получил около 3000 сообщений с использованием Mono 2.8.1 под Ubuntu или 15 сообщений с использованием Visual F# под Windows XP. Я что-то пропустил здесь? Кстати, я попытался заменить оператор printfn следующей операцией с файлом и получил те же частичные результаты.

open System.IO
type Agent<'T> = MailboxProcessor<'T>

let agent =
   Agent.Start(fun inbox ->
     async { while true do
               let! msg = inbox.Receive()
               use logger = new StreamWriter("a.log", true)
               logger.WriteLine("got message '{0}'", msg.ToString())
               logger.Close() 
           } )

for i in 1 .. 10000 do
   agent.Post (sprintf "message %d" i)

person Cygwin98    schedule 01.03.2011    source источник
comment
Я только что проверил, что это работает, используя F # Interactive на компиляторе Mono JIT версии 2.8.1 (tarball Mon 22 Nov 09:52:37 MST 2010) (MacBook). Получил только что-то около 3000 сообщений, они были в порядке? 2000, 2001, 2002 и т.д.? Были пропуски? Пропуски были периодическими?   -  person Chris Smith    schedule 01.03.2011
comment
Привет, Крис, они были в порядке и без пропусков. Я не запускал код в FSI, что, по-видимому, и является причиной. Возможно, именно так Дон ожидал, что читатель запустит код. Просто последовал совету от Desco, и это решило проблему.   -  person Cygwin98    schedule 01.03.2011


Ответы (1)


Просто запустите свой код на Win-машине - все в порядке. Попробуйте добавить

ignore( System.Console.ReadKey() )

в качестве последней строки, потому что agent.Post не блокирует и после публикации 10000 сообщений поток управления будет двигаться вперед, возможно, выходя из программы.

person desco    schedule 01.03.2011
comment
Да, это было так. Спасибо за быстрый ответ. - person Cygwin98; 01.03.2011