C# adresinden bir Posta Kutusu İşlemcisi'ni kullanmaya çalıştınız mı? Örnek kod gönderebilir misiniz?MailboxProcessor <T> C#
Yeni bir tane nasıl başlatırsınız, mesajlar gönderiyor ve bunları nasıl işliyorsunuz?
C# adresinden bir Posta Kutusu İşlemcisi'ni kullanmaya çalıştınız mı? Örnek kod gönderebilir misiniz?MailboxProcessor <T> C#
Yeni bir tane nasıl başlatırsınız, mesajlar gönderiyor ve bunları nasıl işliyorsunuz?
bakmak, bu değil Gerçekten iyi bir şey - Ben özellikle merak için yazdım.
MailboxProcessor<T>
türü F # 'den kullanılacak şekilde tasarlanmıştır, bu nedenle C# programlama modeline uygun değildir. Muhtemelen C# için benzer bir API uygulayabilirsiniz, ancak bu hoş olmaz (kesinlikle C# 4.0'da değil). TPL DataFlow library (CTP), C# 'un sonraki sürümü için benzer bir tasarım sunar.
Şu anda yapılacak en iyi şey, MailboxProcessor<T>
F # öğelerini kullanarak aracı uygulamak ve Task
kullanarak C# kullanımı için kolaylık sağlamaktır. Böylelikle, ajanların çekirdek parçalarını F # (kuyruk geri çekme ve uyumsuz iş akışlarını kullanarak) uygulayabilir ve daha sonra bunları & C# 'dan kullanabilirsiniz.
Bu sorunun doğrudan sorunuzu yanıtlayamayacağını biliyorum, ancak bir örnek vermeye değer olduğunu düşünüyorum - çünkü bu gerçekten F # ajanlarını (MailboxProcessor
) C# ile birleştirmenin tek mantıklı yolu. Ben işte, geçenlerde basit bir "sohbet odası" demo yazdığı bir örnek:
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)
Şimdiye kadar, bu sadece standart F # ajandır. Şimdi, ilginç bitler, GetContent
'u C# 'den kullanılabilen bir eşzamansız yöntem olarak gösteren aşağıdaki iki yöntemdir. yöntem, C# alışılmış bir şekilde kullanılabilir Task
nesne döndürür:
member x.GetContentAsync() =
Async.StartAsTask(agent.PostAndAsyncReply(GetContent))
member x.GetContentAsync(cancellationToken) =
Async.StartAsTask
(agent.PostAndAsyncReply(GetContent),
cancellationToken = cancellationToken)
Bu, (örneğin, vb Task.WaitAll
gibi standart yöntemler kullanılarak) C# 4.0, makul kullanılabilir olacak ve daha da iyi olacaktır C# sonraki sürümü C# await
anahtar sözcüğü ile görevler ile çalışmak mümkün olacak.
Bu çözüm "CTP zaman uyumsuz" C# gerektirir ama (C# async
uzantısını kullanarak) C# doğrudan MailboxProcessor<T>
kullanabilirsiniz ancak benim diğer yanıtında belirttiği gibi Agent/MailboxProcessor in C# using new async/await
Soru: Özellikle ellerim bağlı olduğundan C# 4.0'a doğru ilerliyor. Bunun için bir kalp atışında F # kullanırdım, ama henüz yapamam. Async CTP'nin canlı bir lisansı var mı? – GregC
Tomas P.'nin belirttiği gibi, bu problemin özü, StackOverflowException'a neden olan kuyruk özyinelemeli aramada olurdu. Alternatifler arıyorum. – GregC
@GregC, no go-live lisansına sahip değil. Sadece bir önizleme, isminden de anlaşılacağı gibi, –
Detaylı cevabınız için teşekkür ederiz. Bir şans vereceğim! Tek parça eksik - C# 4.0'dan gerçek kullanım. – GregC