esa*_*sac 2 f# asynchronous tcplistener
在C#中,我使用的是TcpListener/TcpClient的异步版本,我通过回调方法链接这些,以便在回调完成时发布另一个Accept/Read.这是一个例子(未经测试):
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);
}
Run Code Online (Sandbox Code Playgroud)
我的问题是如何在F#中建模类似的东西?我会使用async关键字吗?BeginAcceptTcpClient,BeginRead等之后的代码本质上是将在回调函数中执行的代码吗?例如,这是正确的吗?
let accept(listener:TcpListener) = async {
let! client = listener.AsyncAcceptTcpClient()
// do something with the TcpClient such as beginning a Read chain
accept(listener)
return()
}
Run Code Online (Sandbox Code Playgroud)
上面的代码不起作用,因为未定义accept,并且在技术上标记它是不正确的,因为它不是递归方法?
@kvb的答案是正确和惯用的.
只想指出你可以使用(喘气)一个循环:
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
}
Run Code Online (Sandbox Code Playgroud)
(这是在我的浏览器中键入代码,希望它编译).这很好,因为你当然不能在C#代码中使用循环(必须跨越多个方法使用开始/结束回调).