Task vs AsParallel()
本文关键字:AsParallel vs Task | 更新日期: 2023-09-27 18:20:49
Stephen Toub的《》一书第33页
http://www.microsoft.com/download/en/details.aspx?id=19222
有代码
var pings = from addr in addrs.AsParallel().WithDegreeOfParallelism(16)
select new Ping().Send(addr);
foreach (var ping in pings)
Console.WriteLine("{0}: {1}", ping.Status, ping.Address);
根据Stephen的说法,更好的版本
var pings = (from addr in addrs
select new Ping().SendTask(addr, null)).ToArray();
Task.WaitAll(pings);
foreach (Task<PingReply> ping in pings)
Console.WriteLine("{0}: {1}", ping.Result.Status, ping.Result.Address);
Stephen说第二个选项更好,因为"任务抽象也可以用来表示I/O绑定操作,而不会占用过程"
但是,一个Task不是只使用下面的Threadpool(因此无论如何都只使用线程)吗?所以你实际上是在绑线?
并非所有任务都表示要在线程上完成的工作。几乎所有从TaskCompletionSource
返回的任务都表示某种"其他"的东西。如果我们深入研究SendTask
方法,我们会发现它调用SentTaskCore
:
private static Task<PingReply> SendTaskCore(Ping ping, object userToken, Action<TaskCompletionSource<PingReply>> sendAsync)
{
// Validate we're being used with a real smtpClient. The rest of the arg validation
// will happen in the call to sendAsync.
if (ping == null) throw new ArgumentNullException("ping");
// Create a TaskCompletionSource to represent the operation
var tcs = new TaskCompletionSource<PingReply>(userToken);
// Register a handler that will transfer completion results to the TCS Task
PingCompletedEventHandler handler = null;
handler = (sender, e) => EAPCommon.HandleCompletion(tcs, e, () => e.Reply, () => ping.PingCompleted -= handler);
ping.PingCompleted += handler;
// Try to start the async operation. If starting it fails (due to parameter validation)
// unregister the handler before allowing the exception to propagate.
try
{
sendAsync(tcs);
}
catch(Exception exc)
{
ping.PingCompleted -= handler;
tcs.TrySetException(exc);
}
// Return the task to represent the asynchronous operation
return tcs.Task;
}
所以,不,它不是阻塞线程——它使用异步完成机制来避免阻塞线程。
来自TaskCompletionSource
:上的文档
表示未绑定到委托的Task的生产者端,通过Task属性提供对使用者端的访问。
因此,正如它所说,它支持一个不与委托绑定的Task
——它允许你将一个Task
交给某人,然后在完成任务涉及到比执行委托更重要的事情时,协调该任务的完成方式。