0

我正在编写一个套接字服务器并尝试利用新async / await功能。

我的代码基于这个 stackoverflow 答案

我明白了

mscorlib.dll 中出现“System.OutOfMemoryException”类型的未处理异常

在下面的代码中有什么明显的人可以看到的吗?

public void Main()
{          
    CancellationTokenSource cts = new CancellationTokenSource();
    TcpListener listener = new TcpListener(IPAddress.Any, 6666);

    listener.Start();

    while (true)
    {
        AcceptClientsAsync(listener, cts.Token);
    }

    cts.Cancel();
    listener.Stop();
}

async Task AcceptClientsAsync(TcpListener listener, CancellationToken ct)
{
    while (!ct.IsCancellationRequested)
    {
        TcpClient client = await listener.AcceptTcpClientAsync();
        Console.WriteLine("Client. Doing the do.");
        SomeTaskAsync(client, ct);
    }

}

async Task SomeTaskAsync(TcpClient client, CancellationToken ct)
{
    var stream = client.GetStream();

    while (!ct.IsCancellationRequested)
    {
        // Do Stuff

        stream.Close();
        client.Close();
    }
}
4

1 回答 1

1

原来的代码睡了一觉:

try
{
    listener.Start();
    AcceptClientsAsync(listener, cts.Token);
    Thread.Sleep(60000);
}

你有一个无限繁忙的循环:

while (true)
{
    AcceptClientsAsync(listener, cts.Token);
}

您不能在异步等待模式中执行此操作,您的调用会AcceptClientsAsync立即返回,并且您最终会遇到一个繁忙的无限循环。难怪你打了OOM。

查看异步服务器套接字示例,了解监听循环如何等待循环内的事件。你必须做类似的事情。例如,您可以在完成(接受)时提交新的侦听器。您的 main 必须等待,或者最好仍然为服务器使用适当的模板:服务流程,用于教育。对于现实世界的使用,让框架为您完成繁重的列表,例如。WCF。

于 2013-07-23T10:59:43.050 回答