C#에서 T의 MailboxProcessor를 사용해 보셨습니까? 샘플 코드를 게시 할 수 있습니까?MailboxProcessor <T> from C#
새 메시지를 어떻게 시작하고 메시지를 게시하며 어떻게 처리합니까?
C#에서 T의 MailboxProcessor를 사용해 보셨습니까? 샘플 코드를 게시 할 수 있습니까?MailboxProcessor <T> from C#
새 메시지를 어떻게 시작하고 메시지를 게시하며 어떻게 처리합니까?
살펴보고,이 아니다 정말로 좋은 일 - 나는 호기심을 위해 주로 그것을 썼다.
MailboxProcessor<T>
형식은 F #에서 사용하도록 설계되었으므로 C# 프로그래밍 모델과 잘 맞지 않습니다. 아마도 C# 용 비슷한 API를 구현할 수는 있지만 멋지지 않을 것입니다 (C# 4.0에서는 그렇지 않음). TPL DataFlow library (CTP)은 futrue 버전의 C#과 비슷한 디자인을 제공합니다.
현재 가장 좋은 방법은 F #에서 MailboxProcessor<T>
을 사용하여 에이전트를 구현하고 Task
을 사용하여 C# 사용에 익숙해 지도록하는 것입니다. 이렇게하면 F # (꼬리 재귀 및 비동기 워크 플로 사용)에서 에이전트의 핵심 부분을 구현 한 다음 &을 C#에서 사용하도록 구성 할 수 있습니다.
이 질문에 직접 대답하지 않을 수도 있지만 실제로는 F # 에이전트 (MailboxProcessor
)와 C#을 결합하는 유일한 합리적인 방법이기 때문에 예제를 제시 할 가치가 있다고 생각합니다. 나는, 그래서 여기에 최근 간단한 "채팅방"데모를 쓴 예는 다음과 같습니다
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 번호 에이전트입니다. 이제 재미있는 비트는 C#에서 사용할 수있는 비동기 메서드 인 GetContent
을 노출하는 다음 두 가지 방법입니다. 이 방법은 C 번호로부터 통상의 방법에 사용될 수 Task
객체 리턴
member x.GetContentAsync() =
Async.StartAsTask(agent.PostAndAsyncReply(GetContent))
member x.GetContentAsync(cancellationToken) =
Async.StartAsTask
(agent.PostAndAsyncReply(GetContent),
cancellationToken = cancellationToken)
이것은 (등과 Task.WaitAll
같은 표준 방법을 사용) C# 4.0 합리적 사용할 수있을 것이다 그것은 심지어 좋을 것 C#의 다음 버전 인 C# await
키워드를 사용하여 작업을 수행 할 수 있습니다.
이 솔루션은 "CTP 비동기"는 C#을 필요로하지만 당신은 (는 C# async
확장을 사용)의 C#에서 직접 MailboxProcessor<T>
를 사용할 수 있지만 내 다른 대답에 지적 Agent/MailboxProcessor in C# using new async/await
내 손이 묶여 있으므로이 질문은 C# 4.0에 맞게 조정되었습니다. 나는 이것을 위해 가슴 뛰는 F #을 사용할 것이지만 나는 아직 할 수 없다. Async CTP에 go-live 라이센스가 있습니까? – GregC
Tomas P.에서 지적했듯이이 문제의 핵심은 꼬리 재귀 호출에서 StackOverflowException을 일으킬 수 있다는 것입니다. 나는 대안을 찾고있다. – GregC
@GregC, 아니요. go-live 라이센스가 없습니다. 이름에서 알 수 있듯이 미리보기 일 뿐이므로 제품을 사용하지 말아야합니다. –
자세한 답변 해 주셔서 감사합니다. 나는 그것을 한 번 줄 것이다! 한 조각이 누락되었습니다. C# 4.0의 실제 사용법입니다. – GregC