在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); }
我的问题是如何在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() }
上面的代码不起作用,因为未定义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 }
(这是在我的浏览器中键入代码,希望它编译).这很好,因为你当然不能在C#代码中使用循环(必须跨越多个方法使用开始/结束回调).