2015-06-04 21 views
5

Tôi có đoạn mã sau (giản thể):Nested Async/chờ đợi Không xuất hiện để được Scaling

public async Task GetData(DomainObject domainObject, int depth) 
{ 
    // This async operation is really quick, and there's usually like five. 
    IEnumerable<TierOne> tierOnes = await domainObject.GetTierOnesAsync(); 

    var tierOneTasks = tierOnes.Select(async tierOne => 
    { 
    // This async operation is really quick and there's usually like three. 
    IEnumerable<TierTwo> tierTwos = await tierOne.GetTierTwosAsync(); 

    if (depth <= TierTwoDepth) 
     return; 

    var tierTwoTasks = tierTwos.Select(async tierTwo => 
    { 
     // This async operation is usually fast, and there's usually >= 100. 
     IEnumerable<TierThree> tierThrees = await tierTwo.GetTierThreesAsync(); 

     if (depth <= TierThreeDepth) 
     return; 

     var tierThreeTasks = tierThrees.Select(async tierThree => 
     { 
     // This async operation is SLOW, and there's usually.. 50? 
     await tierThree.GetTierFoursAsync(); 
     }); 

     await Task.WhenAll(tierThreeTasks.ToArray()); 
    }); 

    await Task.WhenAll(tierTwoTasks.ToArray()); 
    }); 

    await Task.WhenAll(tierOneTasks.ToArray()); 
} 

Dựa tắt của những gì tôi đã nhìn thấy, nó dường như không được mở rộng quy mô rất tốt. Tất cả các hoạt động Async là các hoạt động "không đồng bộ đúng" có nghĩa là tất cả chúng đều là I/O.

Tôi có sử dụng Async/Await không chính xác cho trường hợp này không? Dựa trên quan sát hiện tại của tôi, nó không phải là quy mô để những gì tôi mong đợi. Liệu TPL DataFlow có phải là giải pháp của tôi không?

+0

"có vẻ như đang mở rộng quy mô" là lỗi chính tả và bạn muốn đặt một 'không' trong đó? Và nếu vậy, mở rộng quy mô theo cách nào, bạn có hy vọng nó sẽ hoàn thành nhanh hơn hay chỉ không tải quá nhiều vào hệ thống? Bạn thử nghiệm tỉ lệ như thế nào? –

+2

Bạn đang sử dụng rất nhiều 'IEnumerables' làm giá trị trả về không đồng bộ. Bạn có chắc chắn rằng trì hoãn exectution không can thiệp với parallelisation giả định của bạn? – nvoigt

+0

@ScottChamberlain Vâng, đó là lỗi đánh máy. Tôi hy vọng nó sẽ kết thúc nhanh hơn. Tôi hiểu rằng nó sẽ chỉ hoạt động nhanh khi kết thúc hoạt động không đồng bộ của tôi sẽ được xử lý. Có vẻ như nếu tôi tăng lên 1500 nhiệm vụ, tôi mong đợi nhiều hơn chỉ 3 hoặc 4 bị kẹt trong phần 'Đang chờ' của máy trạng thái. (Xin lỗi nếu điều này không có ý nghĩa gì. Nó trễ ở đây, và tôi rất buồn ngủ.) – Cameron

Trả lời

0

Để có một cuộc gọi đến GetData, các cuộc gọi không đồng bộ/chờ đợi lồng nhau sẽ không giới thiệu bất kỳ sự tương tranh nào. Bạn lấy tất cả tierOnes, sau đó tất cả tierTwos cho tierOne- # 1, sau đó tất cả tierThrees cho tierTwo- # 1, và cứ tiếp tục, tất cả chạy theo thứ tự (mặc dù có thể có một số đồng thời bên trong các phương thức GetTier * Async).

Nếu bạn muốn yêu cầu đồng thời, thì TPL Dataflow thực sự là giải pháp tốt hơn.

+0

Tôi không nghĩ rằng đây là trường hợp. Tất cả các nhiệm vụ trong một cấp độ được bắt đầu (chính xác) một cách độc lập (vì ** Chọn ** phương pháp, và "chờ đợi" bởi ** WhenAll ** phương pháp sau). Đồng thời không được giới thiệu bởi async/await nhưng thực tế là LINQ được sử dụng để tạo ra các nhiệm vụ. Điều duy nhất tôi có thể nghĩ đến là anh ta đơn giản chạy ra khỏi luồng, nó xảy ra trong trường hợp bạn đang xử lý các hoạt động async lồng nhau (nó gần giống như đệ quy rõ ràng dừng sau một vài cấp độ - nhưng không phải trước khi thoát ra khỏi hồ bơi thread). –

+0

@ Miklós Khi OP viết, các phương thức 'GetAsync' của anh ta là đúng I/O không đồng bộ, vì vậy chúng không chặn bất kỳ luồng nào trong khi chúng chạy. Tôi chạy 'GetData' (với' Task.Delay' cuộc gọi) từ một 'DispatcherSynchronizationContext', và không có đồng thời, do đó, hồ bơi thread không thể giới hạn hiệu suất. Việc chạy 'GetData' từ một bối cảnh đồng bộ hóa không đưa ra đồng thời, nhưng nếu I/O đến máy chủ chậm hơn mã gửi/nhận (như mô tả OP), các nút cổ chai trong nhóm luồng là một phần nhỏ trong tổng số thời gian chờ đợi. Nút cổ chai của anh ta có thể ở đâu đó khác (như Stephen Cleary gợi ý). –

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