[英]Is it recommended/acceptable to run an async void method into a new thread?
I have an old piece of code (.NET 3.5) where I run in a separate thread the registration of new TcpClient: 我有一段旧代码(.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
}
}
}
The goal of this code is to avoid blocking the app while waiting for new clients. 此代码的目的是避免在等待新客户端时阻止应用程序。 I am porting this code to .NET Standard and I wonder whether I have to use the new features of .NET. 我正在将此代码移植到.NET Standard,我想知道是否必须使用.NET的新功能。
I am talking about async/await
and Task
. 我说的是async/await
和Task
。
Since this thread will last as long as the whole application, I first considered to simply replace the actual method by the new asynchronous one. 由于此线程将与整个应用程序一样长,因此我首先考虑用新的异步方法简单地替换实际方法。 But if I do so, I end up with a new thread running an async void
method: 但是,如果这样做,我最终会得到一个运行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
}
}
}
It is not recommended to write async void
method except in rare case (like event handler). 除极少数情况(如事件处理程序)外,不建议编写async void
方法。
Is this case acceptable? 这种情况可以接受吗?
As a new option, I run the registration in a Task
: 作为一个新选项,我在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
}
}
}
With this code, as long as I do not await
the AcceptConnectionsAsync
call, the app is not blocked (I simplify the code with a while(true)
but I handle the closure of the app and the end of the listening properly, I can call the await there or even fire-and-forget it). 使用此代码,只要我不await
AcceptConnectionsAsync
调用,就不会阻止该应用程序(我使用while(true)
简化了代码,但是我处理了该应用程序的关闭操作并正确地结束了监听,我可以调用等待那里,甚至开火就算了)。
But as I said, this action is supposed to last as long as the whole application, I think a new thread is more appropriate (in term of architecture at least but also in term of efficiency). 但是正如我所说,该操作应该持续整个应用程序的时间,我认为一个新线程更合适(至少在体系结构方面,但在效率方面)。
Am I wrong? 我错了吗?
This is the last option I see. 这是我看到的最后一个选项。 I intended to update the code with the Async/Await
because I read that the async/await improves the performance of the TcpListener. 我打算用Async/Await
Await更新代码,因为我读到async / await可以提高TcpListener的性能。
But is that true? 但这是真的吗?
Here are some information I think can be relevant. 以下是一些我认为可能相关的信息。 Do not hesite to ask for further details. 不要犹豫,要求进一步的细节。
AcceptConnections(Async)
method runs a new Task for each new connection (these tasks are short-lived and of type fire-and-forget). AcceptConnections(Async)
方法为每个新的连接运行一个新的Task(这些任务是短暂的,类型为即发即忘)。 But as I said, this action is supposed to last as long as the whole application 但是正如我所说,此操作应该持续到整个应用程序
No, it doesn't. 不,不是。 The method will return almost immediately. 该方法几乎立即返回。 That's what it means for a method to be asynchronous. 这就是异步方法的含义 。 It doesn't block the caller while the work is being done. 工作完成时,它不会阻止呼叫者。
Creating a new thread just to call an asynchronous method is like hiring someone to come to your house to put a letter in your mailbox for you. 创建一个仅用于调用异步方法的新线程就像雇用某人来您家为您的信箱中放入一封信一样。 It's more work than just doing it yourself, because the actual act of getting the letter to its destination doesn't actually prevent you from doing work outside of a trivial bit of work to just get it started. 它比您自己完成更多的工作,因为将信件发送到目的地的实际行为实际上并不会阻止您仅进行一些琐碎的工作即可开始工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.