2012-04-08 34 views
6

Tôi đang cố gắng thực hiện tác vụ ở chế độ nền mà không làm đóng băng giao diện người dùng.Chạy các tác vụ dài mà không đóng băng Giao diện người dùng

Tất nhiên, tôi có thể sử dụng BackgroundWorker cho việc này.

Tuy nhiên, tôi chỉ muốn làm điều đó với API tác vụ.

tôi đã cố gắng:

async void OnTestLoaded(object sender, RoutedEventArgs e) 
{ 
    await LongOperation(); 
} 
// It freezes the UI 

async void OnTestLoaded(object sender, RoutedEventArgs e) 
{ 
    var task = Task.Run(()=> LongOperation()); 
    task.Wait(); 
} 


// It freezes the UI 

Vì vậy, tôi nên trở về BackgroundWorker? Hay chỉ có một giải pháp bằng cách sử dụng Tác vụ?

+0

Tại sao nhiều người không thích BackgroundWorker? Tôi thích nó và tìm cú pháp trực tiếp. – Paparazzi

+0

'BackgroundWorker' tốt hơn' Thread', nhưng 'API dựa trên Task' cuối cùng sẽ thống trị. Tôi có [một bài đăng blog liên quan] (http://nitoprograms.blogspot.com/2010/08/various-implementations-of-asynchronous.html). 'Task.Run' có những ưu điểm sau: (1) cho phép lồng ghép; (2) hỗ trợ hủy bỏ sử dụng hệ thống 'CancellationToken' hợp nhất; (3) ngoại lệ được tuyên truyền tự nhiên hơn với một ngăn xếp cuộc gọi chính xác; (4) kết quả được lấy tự nhiên hơn; (5) sử dụng ít tài nguyên hơn (nhóm luồng thay vì chuỗi chuyên dụng). –

Trả lời

12

Bạn đã khá thân thiết.

async void OnTestLoaded(object sender, RoutedEventArgs e) 
{ 
    await Task.Run(() => LongOperation()); 
} 

asyncdoes not execute a method on a thread pool thread.

Task.Run thực hiện một thao tác trên một chuỗi nhóm luồng và trả lại một Task biểu thị hoạt động đó.

Nếu bạn sử dụng Task.Wait trong phương thức async, bạn là doing it wrong. Bạn nên await tác vụ trong các phương thức async, không bao giờ chặn chúng.

+0

Có bất kỳ sự khác biệt nào nếu bạn không sử dụng không đồng bộ hoặc đang chờ trong ví dụ cụ thể này không? – Lukazoid

+0

@Lukazoid: Nếu bạn muốn chỉ 'Task.Run' mà không có' đang chờ đợi nó, thì điều đó sẽ lặng lẽ nuốt tất cả các ngoại lệ từ 'LongOperation'. –

+0

Nhưng sẽ không ngoại lệ nếu nuốt phải 'OnTestLoaded' là một 'async void'? Ah, từ đọc thêm, có vẻ như khi sử dụng void không đồng bộ, ngoại lệ sẽ được rethrown trên 'SynchronizationContext' bắt lúc bắt đầu, không có async/await, nó sẽ bị nuốt như bạn đã nói, đúng không? – Lukazoid

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