Async / await套接字服务器OutOfMemoryException

时间:2013-07-23 10:13:11

标签: c# sockets .net-4.5 out-of-memory async-await

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

我的代码是this stackoverflow answer

我得到了

  

发生了类型为“System.OutOfMemoryException”的未处理异常   在mscorlib.dll中

以下代码中是否有任何明显的人可以看到?

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();
    }
}

1 个答案:

答案 0 :(得分:1)

原始代码有一个睡眠:

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

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

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

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

查看Asynchronous Server Socket Example并查看监听循环如何等待循环内的事件。你必须做类似的事情。例如,您可以在完成(接受)时提交新的侦听器。您的主要人员必须等待,或者更好地使用适当的模板作为服务器:服务进程,用于教育。对于现实世界的使用,让框架为您做大量的清单,例如。 WCF。