问题
In C# I am using the asynchronous versions of TcpListener/TcpClient, and I am chaining these via the callback method so that another Accept/Read is posted when the callback completes. Here is an example (untested):
public void Start()
{
TcpListener listener = new TcpListener(IPAddress.Any, 3000);
listener.Start();
PostAccept(listener);
}
private void PostAccept(TcpListener listener)
{
listener.BeginAcceptTcpClient(AcceptCallback, listener);
}
private void AcceptCallback(IAsyncResult ar)
{
var listener = ar.AsyncState as TcpListener;
if (listener == null)
{
return;
}
// get the TcpClient and begin a read chain in a similar manner
PostAccept(listener);
}
My question is how do I model something similar in F#? Would I use the async keyword? Is the code after BeginAcceptTcpClient, BeginRead, etc.. essentially the code that would be executed in the callback function? For example, is this correct?
let accept(listener:TcpListener) = async {
let! client = listener.AsyncAcceptTcpClient()
// do something with the TcpClient such as beginning a Read chain
accept(listener)
return()
}
The above code doesn't work because accept isn't defined, and marking it recursive technically isn't true as it isn't a recursive method?
回答1:
I'm not sure what you mean by "it isn't a recusive method"; if you refer to a function from within its own definition, then it is a recursive function. I don't have much experience with the Sockets classes, but perhaps something along these lines is what you're looking for?
let rec accept(t : TcpListener) =
async {
let! client = t.AsyncAcceptTcpClient()
// do some stuff with client here
do! accept(t)
}
回答2:
@kvb's answer is correct and idiomatic.
Just wanted to also point out you can use (gasp) a loop:
let accept(t:TcpListener) =
let completed = ref false
async {
while not(!completed) do
let! client = t.AsyncAcceptTcpClient()
if client <> null then
Blah(client)
else
completed := true
}
(that was typing code into my browser, hopefully it compiles). Which is nice, since you certainly can't use a loop in the C# code (that has to span multiple methods with the begin/end callbacks).
来源:https://stackoverflow.com/questions/1468145/how-to-do-chained-callbacks-in-f