c# - 任务与 AsParallel()

标签 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);

根据斯蒂芬的说法,更好的版本

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 绑定(bind)操作,而无需在 过程。”

但是任务不只是使用下面的线程池(因此只是使用线程)吗?所以你实际上是在占用线程?

最佳答案

并非所有任务都代表要在线程上完成的工作。几乎所有从 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 上的文档:

Represents the producer side of a Task unbound to a delegate, providing access to the consumer side through the Task property.

因此,正如它所说,它支持未绑定(bind)到委托(delegate)的 Task - 它允许您将 Task 交给某人,然后编排如何当完成涉及执行委托(delegate)以外的其他事情时,任务就完成了。

关于c# - 任务与 AsParallel(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8940834/

相关文章:

c# - Java 和 C# 中的一等对象是什么?

c# - 在 ASP.NET MVC 中创建 Cookie

c# - 开始异步操作,稍后等待

java - 在同一任务中打开另一个应用程序的 Activity ?

c# - 可以使用 plinq ForAll 批量插入数据库吗?

c# - PLINQ ForAll WithCancellation 不起作用

c# - 如何序列化/反序列化从另一个程序集加载的对象?

java - 在 Spring Batch 中使用 split 限制线程数

c# - 为什么 Task 对象不使用传递给它的参数?

c# - AsParallel 使 MonoTouch 应用程序崩溃