2016-02-18 16 views
6

tôi tạo ra đoạn mã sau:async và chờ đợi là đơn luồng Thực sự?

using System; 
using System.Threading.Tasks; 

namespace ConsoleApplication2 
{ 
    class Program 
    { 
     static void Main() 
     { 
     Console.WriteLine("M Start"); 
     MyMethodAsync(); 
     Console.WriteLine("M end"); 
     Console.Read(); 
     } 

    static async Task MyMethodAsync() 
    { 
     await Task.Yield(); 
     Task<int> longRunningTask = LongRunningOperationAsync(); 
     Console.WriteLine("M3"); 
     //and now we call await on the task 
     int result = await longRunningTask; 
     //use the result 
     Console.WriteLine(result); 
    } 

     static async Task<int> LongRunningOperationAsync() 
     { 
     await Task.Delay(1000); 
     return 1; 
     } 
    } 
} 

đầu ra:

M Start 
M end 
M3 
1 

Đó là tốt nhưng khi tôi nhìn vào hồ sơ Chủ đề chương trình của nó này: enter image description here Và rồi này: enter image description here Và sau đó: enter image description here

Vì vậy, có vẻ như như tôi đẻ trứng đề, nhưng từ MSDN nói:

Từ Asynchronous Lập trình với Async và chờ đợi: Chủ đề

Các async và chờ đợi từ khóa không gây đề bổ sung để được tạo. Các phương thức không đồng bộ không yêu cầu đa luồng vì một phương thức async không chạy trên chuỗi riêng của nó. Phương thức này chạy trên ngữ cảnh đồng bộ hiện tại và chỉ sử dụng thời gian trên luồng chỉ khi phương thức hoạt động. Bạn có thể sử dụng Task.Run để di chuyển công việc CPU bị ràng buộc đến chủ đề nền , nhưng một chuỗi nền không hỗ trợ quá trình chỉ chờ kết quả có sẵn.

Tôi có thiếu hoặc không hiểu điều gì đó không? Cảm ơn.

+2

nó sử dụng các chủ đề exisitng từ nhóm chủ đề, không tạo một chủ đề –

+1

Trông giống như một cửa sổ thực sự tiện lợi trong Visual Studio. Xin lỗi cho câu hỏi ngoài chủ đề, nhưng phiên bản nào hỗ trợ? –

+0

Trang trí đầu ra của bạn bằng 'Thread.CurrentThread.ManagedThreadId' và bạn có thể thấy rằng 3 luồng đang được sử dụng. –

Trả lời

7

Tôi giải thích how async and await work with threads and contexts trên blog của mình. Tóm lại, khi await cần đợi một thao tác không đồng bộ để hoàn thành, nó sẽ "tạm dừng" phương thức async hiện tại và (theo mặc định) chụp một "ngữ cảnh".

Khi hoạt động không đồng bộ hoàn tất, "ngữ cảnh" đó được sử dụng để tiếp tục phương thức async. "Ngữ cảnh" này là SynchronizationContext.Current, trừ khi nó là null, trong trường hợp này là TaskScheduler.Current. Trong trường hợp của bạn, ngữ cảnh kết thúc là bối cảnh của luồng chủ đề, do đó phần còn lại của phương thức async được gửi đến nhóm luồng. Nếu bạn chạy cùng một mã từ chuỗi giao diện người dùng, ngữ cảnh sẽ là ngữ cảnh giao diện người dùng và tất cả các phương thức async sẽ tiếp tục trên chuỗi giao diện người dùng.

2

Từ khóa không đồng bộ và đang chờ không tạo thêm chủ đề.

Có. Nó di chuyển CPU bị ràng buộc hoặc I/O bị ràng buộc làm việc với thread khác từ thread thread của quá trình để nó không được thực hiện trên UI thread hoặc hiện tại đồng bộ hóa bối cảnh, nó không tạo ra một chủ đề mới đó là những gì có nghĩa trong mô tả MSDN .

+0

nhưng nếu tất cả các chuỗi đang được tiêu thụ thì nó sẽ đợi. Đúng? –

+1

Đây chỉ là sai. Các tác vụ được thực hiện trên ngữ cảnh đồng bộ hóa hiện tại. Một luồng khác chỉ được sử dụng nếu bạn sử dụng ngữ cảnh đồng bộ dựa trên threadpool, nếu không mọi thứ được thực hiện trên luồng chính với một hàng đợi. Đọc về "kiểu chuyển tiếp tiếp tục", đó là cách hoạt động của async bên dưới. –

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