2013-07-23 56 views
0

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

我根据我的代码关闭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

原代码有睡眠:

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

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

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

不能在异步为此等待模式,您的来电AcceptClientsAsync立即返回并最终导致无限循环。难怪你打了OOM。

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

+0

感谢您的回答。我应该在我的情况下使用异步等待模式吗?目标是简化代码。 –

+0

是的,异步等待仍然很棒。来自MSDN示例的异步示例可以轻松移植到异步等待。更好的是,我确定有一个异步等待特定样本。 –

+0

你会认为会有一个例子,但到目前为止,我找不到一个。 –