Это на самом деле не ответ на ваш вопрос, а просто комментарий относительно цикла и Async.Start
(я думаю, что версия gradbot, вероятно, должна работать, отвечая на ваш главный вопрос).
В любом случае, в отличие от Даниэля и Грэдбота, я думаю, что вы использовали Async.Start
не неправильно , но, возможно, просто сбивают с толку (и вводят в заблуждение название).
Способ, которым вы реализовали это, заключается в том, что вы ждете сокет, затем запускаете новый асинхронный режим (готов к немедленному принятию нового сокета) и затем обрабатываете остальную часть работы. Это означает, что вы можете обрабатывать запросы параллельно.
Способ, который реализовали gradbot и Daniel, заключается в том, что они принимают сокет, отправляют ответ вызывающей стороне и затем ждут другого сокета. Это означает, что обработка является последовательной!
Я думаю, что путаница возникла из-за того, как вы ее написали - я, вероятно, начал бы обработку текущего сокета как нового асинхронного рабочего процесса, а затем ждал бы следующего сокета (я думаю, это легче понять, но я думаю, что ваш версия тоже была верна):
// Asynchronous function that handles communication with a single client
let handleClient (tcp:TcpClient) =
async {
try
let stream = tcp.GetStream()
use streamWriter = new StreamWriter(stream)
use content = writeContent()
streamWriter.WriteLine("HTTP/1.0 200 OK")
// Some stuff omitted
streamWriter.Flush()
content.WriteTo stream
stream.Flush()
finally
tcp.Dispose()
}
let mainLoop =
async {
while true do
// Wait for a client and start async workflow to process it
let! tcp = tcpListener.AsyncAcceptTcpClient()
Async.Start(handleClient tcp) }