我有一个Threading.Tasks.Task,它处理许多客户端套接字操作(连接,接收和发送)。
据我所知,在可能的情况下,最好使用Await使用非阻塞方法,否则我会以#34;停放的线程等待他们的响应"。但是,虽然Socket类具有异步方法(SendAsync等),但它们与通常的任务并行库异步方法不同,它们不会返回任务而无法等待。
我意识到我可以使用TaskCompletionSource包装这些套接字异步方法,但这样做有什么好处还是最终还是会停止线程?
答案 0 :(得分:13)
正如Servy解释的那样。只要您正确使用异步模式,使用TaskCompletionSource
本身并不会创建(或停放)任何线程。
.Net框架中有3种不同的异步模式:
你想要实现的目标是"转换"一种模式,即EAP,另一种模式,TAP。一个更简单的解决方案是使用.Net的内置"转换"从APM模式到TAP,Task.Factory.FromAsync
(内部使用TaskCompletionSource
):
socket.BeginConnect(host, port, asyncResult =>
{
socket.EndConnect(asyncResult);
Console.WriteLine("Socket connected");
}, null);
await Task.Factory.FromAsync(socket.BeginConnect, socket.EndConnect, host, port, null);
Console.WriteLine("Socket connected");
答案 1 :(得分:2)
通过使用TaskCompletionSource
将基于非任务的异步模型转换为基于任务的异步模型不会创建任何新线程,不会。它只允许您使用不同的语法与该异步操作进行交互。
它不客观地好或坏,它只是做同样事情的不同语法。主观上基于任务的模型往往更容易使用,但两个模型的整体设计意味着它们最终会做同样的功能,假设每个模型都正确使用。