我有一段旧代码(.NET 3.5),我在一个单独的线程中运行新TcpClient的注册:
public class TcpServer
{
private readonly TcpListener _tcpListener;
public TcpServer(int port)
{
_tcpListener = new TcpListener(IPAddress.Any, port);
}
public void StartListening()
{
_tcpListener.Start();
var t = new Thread(new ThreadStart(AcceptConnections));
t.Start();
}
private void AcceptConnections()
{
while (true)
{
var client = _tcpListener.AcceptTcpClient();
// Some stuff
}
}
}
此代码的目标是避免在等待新客户端时阻止应用程序。我正在将此代码移植到.NET Standard,我想知道是否必须使用.NET的新功能。
我正在谈论async/await
和Task
。
由于该线程将与整个应用程序一样长,因此我首先考虑用新的异步方法简单地替换实际方法。但是,如果这样做,我最终得到一个运行async void
方法的新线程:
public class TcpServer
{
private readonly TcpListener _tcpListener;
public TcpServer(int port)
{
_tcpListener = new TcpListener(IPAddress.Any, port);
}
public void StartListening()
{
_tcpListener.Start();
var t = new Thread(new ThreadStart(AcceptConnectionsAsync));
t.Start();
}
private async void AcceptConnectionsAsync()
{
while (true)
{
var client = await _tcpListener.AcceptTcpClientAsync();
// Some stuff
}
}
}
除极少数情况(如事件处理程序)外,不建议编写async void
方法。
这种情况可以接受吗?
作为一个新选项,我在Task
中运行注册:
public class TcpServer
{
private readonly TcpListener _tcpListener;
public TcpServer(int port)
{
_tcpListener = new TcpListener(IPAddress.Any, port);
}
public Task StartListeningAsync()
{
_tcpListener.Start();
return Task.Run(async () => await AcceptConnectionsAsync());
}
private async Task AcceptConnectionsAsync()
{
while (true)
{
var client = await _tcpListener.AcceptTcpClientAsync();
// Some stuff
}
}
}
使用此代码,只要我不await
进行AcceptConnectionsAsync
调用,就不会阻止该应用程序(我使用while(true)
简化了代码,但是我处理了应用程序,并且听音结束正常,我可以在那叫await甚至开火然后忘记它。
但是,正如我所说的那样,该操作应该持续整个应用程序的时间,我认为一个新的线程更合适(就架构而言,至少在效率方面)。
我错了吗?
这是我看到的最后一个选项。我打算用Async/Await
更新代码,因为我读到异步/等待可以提高TcpListener的性能。
但这是真的吗?
以下是一些我认为可能相关的信息。不要犹豫,要求进一步的细节。
AcceptConnections(Async)
方法为每个新连接运行一个新的Task(这些任务是短暂的,并且类型为即发即弃)。答案 0 :(得分:0)
但是正如我所说,该操作应该持续整个应用程序
不,不是。该方法几乎立即返回。这就是异步方法的意思。工作完成时,它不会阻止呼叫者。
创建一个仅用于调用异步方法的新线程,就像雇用某人来您家为您的邮箱中放一封信一样。这比您自己完成更多的工作,因为将信发送到目的地的实际行为实际上并不能阻止您仅在开始工作时就进行一些琐碎的工作。