2013-07-23 80 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

你會認爲會有一個例子,但到目前爲止,我找不到一個。 –