2015-02-23 56 views
9

Tôi đang cố gắng để hiểu được cách tiếp cận tốt nhất để sử dụng khi gọi một phương pháp async rằng cập nhật ViewModel của tôi là gì. Ngay bây giờ, chúng ta hãy nói rằng tôi có một cái gì đó như thế này:Cách tốt nhất để thực hiện một async "loadData" phương pháp sử dụng mô hình MVVM

Xem:

private async void NavigationHelper_LoadState(object sender, LoadStateEventArgs e) 
{ 
    //Call my ViewModel method to update the data the UI is bound to   
} 

ViewModel:

public async Task loadData() 
{ 
    this.Source = await loadStuffFromDatabaseAsync(); 
} 

Bây giờ, tôi không chắc chắn mà một trong những điều sau đây cách tiếp cận tôi nên sử dụng:

1) Trong phương pháp loadstate của tôi, sử dụng:

await Task.Run(async() => { await ViewMode.loadData(); }); 

2) Sử dụng Task.Run mà không cần chờ đợi loadData phương pháp bên trong Action :

await Task.Run(() => { ViewModel.loadData(); }); 

3) Gọi phương pháp tảiData của chúng tôi với:

await ViewModel.loadData().ConfigureAwait(false); 

4) Gọi loadData phương pháp mà không cần chờ nó trong tôi Xem lớp và sử dụng Task.Run bên trong phương pháp loadData tôi:

Xem:

private void NavigationHelper_LoadState(object sender, LoadStateEventArgs e) 
{ 
    ViewModel.loadData(); 
} 

Xem Mô hình:

public async void loadData() 
{ 
    await Task.Run(async() => 
    { 
     this.Source = await loadStuffFromDatabaseAsync(); 
    }); 
} 

Sự khác biệt chính giữa các phê duyệt này là gì?

là một hiệu quả hơn rằng người khác, và tôi nên chọn một trong cụ thể không?

Cảm ơn sự giúp đỡ của bạn! :)

Sergio

+0

async trống phương pháp này cần phải tránh, và bạn nên làm theo quy ước đặt tên của phụ Async cho tất cả các phương pháp async. –

+0

Tôi tin rằng Reed Cosby đã dạy tất cả những gì chúng ta cần bây giờ vì sự hỗ trợ của Asynch được tích hợp vào mã cơ sở là hai từ Async và Await. Chúng tôi không còn cần gọi các phương thức Task nữa. –

+2

@JohnPeters: Điều đó không đúng. Có thể có mã đang chặn chuỗi giao diện người dùng. – Fred

Trả lời

2

Bạn chỉ nên sử dụng Task.Run nếu bạn có CPU-bound hoặc chặn công việc mà bạn muốn di chuyển ra khỏi thread UI. Đó không phải là trường hợp ở đây, do đó, các cuộc gọi trực tiếp (tùy chọn 3) là tự nhiên nhất.

Lấy họ lần lượt:

await Task.Run(async() => { await ViewMode.loadData(); }); 

Tùy chọn này sẽ thực hiện loadData trên một thread hồ bơi. Điều này có thể không hoạt động tốt, vì loadData đang cập nhật giao diện người dùng (gián tiếp bằng cách đặt thuộc tính VM). Ngay cả khi nó xảy ra để làm việc (tức là, một số khung MVVM có thể xử lý đúng các cập nhật từ các chủ đề nền trong một số tình huống), có lẽ không cần thiết vì loadData là một phương pháp không đồng bộ.

Hơn nữa, nó bổ sung thêm async chi phí máy ở trạng thái không có lý do.

await Task.Run(() => { ViewModel.loadData(); }); 

Tùy chọn này có tất cả các vấn đề tương tự, ngoại trừ nó hiệu quả hơn một chút vì nó không có chi phí máy ở trạng thái async. Nhưng nó vẫn đang cập nhật các thuộc tính VM trên một luồng nền và sử dụng một luồng nền không cần thiết.

public async void loadData() 

Đây là điều tồi tệ nhất. Nó thừa kế các vấn đề tương tự của những người khác: cập nhật các thuộc tính VM trên một luồng nền và sử dụng một luồng nền không cần thiết. Để nó thêm các vấn đề của async void. Một vấn đề là NavigationHelper_LoadState không thể bắt bất kỳ ngoại lệ nào từ loadData. Một vấn đề khác là loadData không dễ dàng kiểm chứng được.

Vì vậy, chỉ cần sử dụng các phương pháp đơn giản và gọi nó là trực tiếp:

await ViewModel.loadData().ConfigureAwait(false); 
+0

Cảm ơn câu trả lời của bạn! Tôi chỉ có một nghi ngờ: bạn nói tôi nên sử dụng Task.Run cho CPU bị ràng buộc hoặc ngăn chặn công việc chỉ: tại sao không tải dữ liệu từ một số cơ sở dữ liệu như là một công việc ngăn chặn? Vì nó là một hoạt động IO, có thể mất một thời gian dài để hoàn thành, và do đó chặn các phương pháp gọi đang chờ đợi nhiệm vụ đó? – Sergio0694

+1

Chủ đề không bị chặn vì đó là thao tác không đồng bộ. –

+0

Bạn nói đúng, bằng cách "chặn công việc", bạn có nghĩa là một số mã đồng bộ để chạy. Cảm ơn một lần nữa vì sự giúp đỡ của bạn :) – Sergio0694

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