我正在尝试学习async/await
所以这可能听起来像一个愚蠢的问题,但我目前正在研究基本的TCP服务器并尝试使用async/await
而不是手动线程来处理多个连接。
在NetworkClient
课程中,我有以下方法:
public async Task Start()
{
using (var reader = new StreamReader(_socket.GetStream()))
{
while (_server.IsRunning)
{
try
{
var content = await reader.ReadLineAsync().ConfigureAwait(false);
if (content == null)
{
Console.WriteLine("Client {0} disconnected", _id);
return;
}
Console.WriteLine("Client {0} wrote: {1}", _id, content);
}
catch (IOException)
{
Console.WriteLine("Client {0} disconnected", _id);
return;
}
}
}
}
我的侦听客户端连接的循环包含以下代码:
private void ListenForClients()
{
var numClients = 0;
while (IsRunning)
{
var tcpClient = _listener.AcceptTcpClient();
var netClient = new NetworkClient(this, tcpClient, numClients);
netClient.Start();
Console.WriteLine("Client {0} Connected", numClients);
numClients++;
}
}
这符合我的预期,允许多个telnet连接同时连接并向服务器发送消息。但是,resharper告诉我,我应该将await
添加到netClient.Start();
,否则它不会阻止。但是,我不希望它阻止!
Resharper正在给我这样的警告这一事实让我想知道我是否错误地接近async/await
系统。为什么Resharper希望我在此代码行中添加await
,以及使用此代码的正确方法是什么,以便netClient.Start();
不阻止其他tcp连接加入?
答案 0 :(得分:3)
然而,resharper告诉我,我应该添加等待netClient.Start();因为否则它不会阻止。但是,我不希望它阻止!
ReSharper会警告这种情况,因为这通常是一个错误。
在您的情况下,您可以在类型中创建代表private Task
方法的Start
成员,然后分配该成员而不是await
:
startTask = netClient.Start();
这应该避免警告,并使您能够确定Start
方法何时退出并检测它抛出的任何异常。
答案 1 :(得分:0)
你Start
方法实际上不是异步的 - 看起来它等待连接同步发生而不是异步读取数据。因此,ListenForClients
中的代码实际上按预期方式工作 - Start
的同步部分在Console.WriteLine
之前完成(因此它打印正确的文本),而异步部分将自行运行而没有任何人等待结果。
此代码与“connect + fire并忘记处理数据的新线程”基本相同。
当您需要使用异步操作编写顺序代码时, async
/ await
会闪耀。在你的情况下,你真的需要并行操作 - 一些其他构造可能更好地启动多个侦听器。每个侦听器的代码都可能有利于使用await
- 使用await read / await write更简单,而不是带有事件的多个状态(甚至更糟糕的是EndSend / SendReceive ...)。