async 比 BeginXXX/EndXXX 有什么优势?
What is the advantage of async over BeginXXX/EndXXX?
在寻找一种优雅的方式从 UDP 套接字异步接收数据报流时,我遇到了这个问题:How to use asynchronous Receive for UdpClient in a loop?
我理解第一个答案的优点,因为他们使用熟悉的 BeginReceive
/EndReceive
方法。这个解决方案很好,因为没有线程被阻塞。
然而,second answer 给出了两种不同的 Task-ish 解决方案,一种使用 ReceiveAsync
,另一种使用同步 Receive
方法。我想知道,在这种情况下,优势是什么。据我了解,即使在 ReceiveAsync
情况下,仍然有一个(线程池?)线程在等待事情发生。
在这种情况下使用异步方法有优势吗?如果没有,是否有一种方法可以使用异步方法来实现这种类型的模式,而无需线程、任务或其他阻塞对象的开销?
好吧,不是分配一个线程池线程等待异步操作完成。相反,它分配一个线程池线程来 start 异步操作,而不是在当前线程中启动它。
确实没有任何理由这样做,至少除非启动异步操作的行为需要很长时间,而且如果编写正确则不应该这样做。
你能在不在线程池线程中启动异步操作的情况下实现同样的事情吗,当然,只需删除在线程池线程中启动它的代码。
首先,在自然异步 API 中,async-await
(TAP) 版本和 Begin/End
(APM) (There Is No Thread 中都没有阻塞线程).
然而,在这种特定情况下,链接的答案确实不必要地浪费了 ThreadPool
线程,应该避免这种情况。
ReceiveAsync
案例将操作的同步部分(直到 await ReceiveAsync
)卸载到 ThreadPool
线程。如果您要执行实质性的 CPU 绑定操作并且您想要释放调用线程,这将很有用。这似乎并非如此,因为除了创建客户端之外别无他法。
您可以简单地删除 Task.Run
并使用 async
方法:
async Task ListenAsync(int port, CancellationToken token)
{
using (var client = new UdpClient(port))
{
while (true)
{
var result = await client.ReceiveAsync().WithCancellation(token).ConfigureAwait(false);
// process result.Buffer
}
}
}
在寻找一种优雅的方式从 UDP 套接字异步接收数据报流时,我遇到了这个问题:How to use asynchronous Receive for UdpClient in a loop?
我理解第一个答案的优点,因为他们使用熟悉的 BeginReceive
/EndReceive
方法。这个解决方案很好,因为没有线程被阻塞。
second answer 给出了两种不同的 Task-ish 解决方案,一种使用 ReceiveAsync
,另一种使用同步 Receive
方法。我想知道,在这种情况下,优势是什么。据我了解,即使在 ReceiveAsync
情况下,仍然有一个(线程池?)线程在等待事情发生。
在这种情况下使用异步方法有优势吗?如果没有,是否有一种方法可以使用异步方法来实现这种类型的模式,而无需线程、任务或其他阻塞对象的开销?
好吧,不是分配一个线程池线程等待异步操作完成。相反,它分配一个线程池线程来 start 异步操作,而不是在当前线程中启动它。
确实没有任何理由这样做,至少除非启动异步操作的行为需要很长时间,而且如果编写正确则不应该这样做。
你能在不在线程池线程中启动异步操作的情况下实现同样的事情吗,当然,只需删除在线程池线程中启动它的代码。
首先,在自然异步 API 中,async-await
(TAP) 版本和 Begin/End
(APM) (There Is No Thread 中都没有阻塞线程).
然而,在这种特定情况下,链接的答案确实不必要地浪费了 ThreadPool
线程,应该避免这种情况。
ReceiveAsync
案例将操作的同步部分(直到 await ReceiveAsync
)卸载到 ThreadPool
线程。如果您要执行实质性的 CPU 绑定操作并且您想要释放调用线程,这将很有用。这似乎并非如此,因为除了创建客户端之外别无他法。
您可以简单地删除 Task.Run
并使用 async
方法:
async Task ListenAsync(int port, CancellationToken token)
{
using (var client = new UdpClient(port))
{
while (true)
{
var result = await client.ReceiveAsync().WithCancellation(token).ConfigureAwait(false);
// process result.Buffer
}
}
}