任务与AsParallel()

The*_*ies 6 c# task plinq

在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);
Run Code Online (Sandbox Code Playgroud)

并且据斯蒂芬说的更好的版本

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);
Run Code Online (Sandbox Code Playgroud)

Stephen说第二个选项更好,因为"任务抽象也可以用来表示I/O绑定操作,而不会在进程中占用一个线程."

但是,任务是不是只使用Threadpool(因此无论如何只使用线程)?所以你实际上是在捆绑一个线程?

Dam*_*ver 4

并非所有任务都代表要在线程上完成的工作。几乎任何返回的任务都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;
    }
Run Code Online (Sandbox Code Playgroud)

所以,不,它不会阻塞线程 - 它使用异步完成机制来避免占用线程。


从文档中TaskCompletionSource

表示未绑定到委托的任务的生产者端,通过 Task 属性提供对消费者端的访问。

因此,正如它所说,它支持Task不绑定到委托的 a - 它允许您将 a 交给某人Task,然后在完成涉及执行委托以外的其他事情时编排该任务的完成方式。