2012-01-20 23 views
6

Trên trang 33 của cuốn sách Stephen Toub củacông tác vs AsParallel()

http://www.microsoft.com/download/en/details.aspx?id=19222

Có mã

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

và theo Stephen phiên bản tốt hơn

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 nói tùy chọn thứ 2 là tốt hơn bởi vì "Tóm tắt tác vụ cũng có thể được sử dụng để biểu diễn I/O-ràng buộc hoạt động và không có buộc lên một sợi trong quá trình . "

Nhưng không phải một tác vụ chỉ sử dụng Threadpool (do đó chỉ sử dụng luồng anyway) bên dưới? Vì vậy, bạn đang trong thực tế buộc lên một sợi?

+2

"không phải Tác vụ chỉ sử dụng Threadpool" - điều đó sẽ không có nhiều trừu tượng. –

Trả lời

4

Không phải tất cả các tác vụ đều thể hiện công việc được thực hiện trên một chuỗi. Chỉ là về bất kỳ nhiệm vụ nào được trả lại từ TaskCompletionSource đại diện cho một cái gì đó "khác". Và nếu chúng ta đi sâu vào phương pháp SendTask, chúng tôi tìm thấy nó gọi 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; 
    } 

Vì vậy, không có, nó không chặn a thread - nó bằng cách sử dụng cơ chế hoàn async để tránh buộc lên một sợi dây.


Từ các tài liệu trên TaskCompletionSource:

Đại diện phía nhà sản xuất của một nhiệm vụ không liên kết với một đại biểu, cung cấp quyền truy cập vào phía người tiêu dùng thông qua việc sở hữu công tác.

Vì vậy, như nó nói, nó hỗ trợ một Task không được ràng buộc với một đại biểu - nó cho phép bạn trao cho ai đó một Task, và sau đó dàn xếp như thế nào nhiệm vụ được hoàn thành, khi hoàn thành một cái gì đó liên quan đến khác hơn là thực hiện một đại biểu.

+1

Chỉ cần làm rõ, mặc dù tôi không hiểu đầy đủ mã nhưng bạn có thể làm "cơ chế hoàn thành không đồng bộ" mà không cần sử dụng một Chủ đề? Sao có thể như thế được? khi tôi đã BeginInvoke trên một hành động họ nói với tôi nó thực sự được gửi đi trên một threadpool. – TheWommies

Các vấn đề liên quan