Вы пытались использовать MailboxProcessor из T с С#? Не могли бы вы разместить образец кода?
Как вы начинаете новый, публикуете сообщения и как их обрабатываете?
Вы пытались использовать MailboxProcessor из T с С#? Не могли бы вы разместить образец кода?
Как вы начинаете новый, публикуете сообщения и как их обрабатываете?
В то время как вы можете использовать MailboxProcessor<T>
непосредственно из С# (используя расширение С# async
), как указано в моем другом ответе, это не очень хорошо - я написал это в основном для любопытства.
Тип MailboxProcessor<T>
был разработан для использования с F #, поэтому он не подходит для модели программирования С#. Возможно, вы могли бы реализовать аналогичный API для С#, но это было бы не так хорошо (конечно, не в С# 4.0). библиотека TPL DataFlow (CTP) обеспечивает аналогичный дизайн для версии Futrue С#.
В настоящее время лучше всего реализовать агент с помощью MailboxProcessor<T>
в F # и сделать его удобным для использования С# с помощью Task
. Таким образом, вы можете реализовать основные части агентов в F # (используя хвостовую рекурсию и асинхронные рабочие процессы), а затем составить и использовать их с С#.
Я знаю, что это не может напрямую ответить на ваш вопрос, но я думаю, что стоит привести пример, потому что это действительно единственный разумный способ объединить агентов F # (MailboxProcessor
) с С#.
Недавно я написал простую демонстрацию "чат-комнаты", вот пример:
type internal ChatMessage =
| GetContent of AsyncReplyChannel<string>
| SendMessage of string
type ChatRoom() =
let agent = Agent.Start(fun agent ->
let rec loop messages = async {
// Pick next message from the mailbox
let! msg = agent.Receive()
match msg with
| SendMessage msg ->
// Add message to the list & continue
let msg = XElement(XName.Get("li"), msg)
return! loop (msg :: messages)
| GetContent reply ->
// Generate HTML with messages
let html = XElement(XName.Get("ul"), messages)
// Send it back as the reply
reply.Reply(html.ToString())
return! loop messages }
loop [] )
member x.SendMessage(msg) = agent.Post(SendMessage msg)
member x.AsyncGetContent() = agent.PostAndAsyncReply(GetContent)
member x.GetContent() = agent.PostAndReply(GetContent)
До сих пор это всего лишь стандартный агент F #. Теперь интересными битами являются следующие два метода, которые раскрывают GetContent
как асинхронный метод, который можно использовать из С#. Метод возвращает объект Task
, который может использоваться обычным образом из С#:
member x.GetContentAsync() =
Async.StartAsTask(agent.PostAndAsyncReply(GetContent))
member x.GetContentAsync(cancellationToken) =
Async.StartAsTask
( agent.PostAndAsyncReply(GetContent),
cancellationToken = cancellationToken )
Это будет разумно использоваться с С# 4.0 (с использованием стандартных методов, таких как Task.WaitAll
и т.д.), и это будет еще лучше в следующей версии С#, когда вы сможете использовать ключевое слово С# await
для работы с задачами.
Это решение требует С# "async CTP", но посмотрите Agent/MailboxProcessor в С#, используя новый async/wait