2012-12-18 43 views
7

Tôi đã đọc rằng 'Người tạo nền tảng' là designed to be replaced bởi Ansyc/Await.Có phải chờ đợi thực hiện phần còn lại của phương thức không đồng bộ không?

Vì tôi thích giao diện của Async/Await, tôi bắt đầu chuyển đổi một số BackgroundWorkers của tôi thành các cuộc gọi Async/Await.

Đây là một ví dụ về đoạn code tôi có (gọi là từ UI):

public async void RunFromTheUI() 
{ 
    await OtherAction(); 
} 

public async void OtherAction() 
{ 
    var results = await services.SomeRemoteAction(); 

    foreach (var result in results) 
    { 
     result.SemiIntenseCalculation(); 
     Several(); 
     Other(); 
     NonAsync(); 
     Calls(); 
    } 

    SomeFileIO(); 
} 

Khi tôi gọi RunFromTheUI nó sẽ trở lại gần như ngay lập tức (theo Async và đang chờ đợi thiết kế).

Nhưng khi nó tiếp tục sau khi services.SomeRemoteAction() kết thúc, nó có một vòng lặp foreach và một cuộc gọi phương thức khác để chạy qua.

Câu hỏi của tôi là: Nếu vòng lặp đó là một con heo hiệu suất sẽ đóng băng giao diện người dùng? (Trước khi tôi có tất cả trong một chuỗi công nhân nền, do đó, nó không làm chậm giao diện người dùng).

Lưu ý: Tôi đang nhắm mục tiêu .Net 4.0 và sử dụng Gói phần mềm Async Nuget.

+0

không đồng bộ/chờ đợi và BackgroundWorker giải quyết hai vấn đề khác nhau. Nhân viên BG được thay thế chính xác hơn bằng Nhiệm vụ. Async chỉ thay thế những mã này khi mã cơ thể của nhân viên cơ bản là nhàn rỗi, nơi BGW/Tasks vẫn hữu ích khi bạn cần nâng cấp nặng. Tôi có vẻ như bạn đang chờ đợi kết quả dịch vụ trong câu hỏi của bạn, chỉ là FYI. –

+0

1. Mã của bạn sẽ không biên dịch, bạn không thể 'chờ đợi' phương thức 'async void'. 2. Bạn nên tránh sử dụng các phương thức 'async void', chúng không thể được 'chờ đợi' và làm cho việc xử lý ngoại lệ trở nên khó khăn hơn. – svick

Trả lời

6

Câu hỏi của tôi là: Nếu vòng lặp đó là một con heo hiệu suất sẽ đóng băng giao diện người dùng?

Có, nó sẽ. Phần còn lại của phương thức async sẽ vẫn thực hiện trên luồng UI khi hành động từ xa đã hoàn thành. Nếu bạn không muốn điều đó xảy ra, thì tùy chọn là:

  • Sử dụng ConfigureAwait(continueOnCapturedContext: false) để tiếp tục không thực thi trên thread UI
  • Execute toàn của phương pháp này trong một chủ đề khác nhau để bắt đầu, sử dụng Task.Run. (Bạn vẫn có thể làm cho nó trở thành một phương pháp không đồng bộ, để tránh chặn một sợi khi bạn không cần.)

Về cơ bản, nếu bạn có tải trọng của cuộc gọi đồng bộ, chặn hoặc công việc chuyên sâu CPU , bạn muốn tránh điều đó xảy ra trên chuỗi giao diện người dùng, điều này ngược lại với những gì async/await thực hiện cho bạn theo mặc định.

+1

'Task.Run' có giá trị mặc định tốt hơn' Task.Factory.StartNew' nếu bạn đang sử dụng 'async'. [Stephen Toub đi vào chi tiết.] (Http://blogs.msdn.com/b/pfxteam/archive/2011/10/24/10229468.aspx) –

+0

@StephenCleary: Cố định, cảm ơn. Tôi đã không chú ý - 'Task.StartNew' không hợp lệ để bắt đầu với, tất nhiên :) –

+0

Jon: Bất kỳ điểm khởi đầu tốt nào để đọc/hiểu không đồng bộ/chờ đợi, công việc? – shahkalpesh

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