Tôi muốn hỏi bạn về ý kiến của bạn về kiến trúc chính xác khi sử dụng Task.Run
. Tôi đang gặp phải giao diện người dùng bị lag trong ứng dụng WPF .NET 4.5 của chúng tôi (với khung Caliburn Micro).
Về cơ bản tôi đang làm (đoạn mã rất đơn giản):
public class PageViewModel : IHandle<SomeMessage>
{
...
public async void Handle(SomeMessage message)
{
ShowLoadingAnimation();
// Makes UI very laggy, but still not dead
await this.contentLoader.LoadContentAsync();
HideLoadingAnimation();
}
}
public class ContentLoader
{
public async Task LoadContentAsync()
{
await DoCpuBoundWorkAsync();
await DoIoBoundWorkAsync();
await DoCpuBoundWorkAsync();
// I am not really sure what all I can consider as CPU bound as slowing down the UI
await DoSomeOtherWorkAsync();
}
}
Từ các bài viết / video tôi đã đọc / xem, tôi biết rằng await
async
không nhất thiết phải chạy trên một chủ đề nền và để bắt đầu công việc trong nền bạn cần phải chờ nó Task.Run(async () => ... )
. Việc sử dụng async
await
không chặn UI, nhưng nó vẫn đang chạy trên luồng UI, vì vậy nó làm cho nó bị lag.
Đâu là nơi tốt nhất để đặt Task.Run?
Tôi có nên chỉ
Kết thúc cuộc gọi bên ngoài vì đây là công việc phân luồng ít hơn cho .NET
hoặc tôi chỉ nên bọc các phương thức gắn với CPU bên trong khi chạy với
Task.Run
điều này làm cho nó có thể sử dụng lại cho những nơi khác? Tôi không chắc chắn ở đây nếu bắt đầu làm việc trên các chủ đề nền sâu trong cốt lõi là một ý tưởng tốt.
Quảng cáo (1), giải pháp đầu tiên sẽ như thế này:
public async void Handle(SomeMessage message)
{
ShowLoadingAnimation();
await Task.Run(async () => await this.contentLoader.LoadContentAsync());
HideLoadingAnimation();
}
// Other methods do not use Task.Run as everything regardless
// if I/O or CPU bound would now run in the background.
Quảng cáo (2), giải pháp thứ hai sẽ như thế này:
public async Task DoCpuBoundWorkAsync()
{
await Task.Run(() => {
// Do lot of work here
});
}
public async Task DoSomeOtherWorkAsync(
{
// I am not sure how to handle this methods -
// probably need to test one by one, if it is slowing down UI
}
await Task.Run(async () => await this.contentLoader.LoadContentAsync());
nên đơn giản làawait Task.Run( () => this.contentLoader.LoadContentAsync() );
. AFAIK bạn không đạt được bất cứ điều gì bằng cách thêm một giâyawait
vàasync
bên trongTask.Run
. Và vì bạn không truyền tham số, điều đó đơn giản hóa hơn một chútawait Task.Run( this.contentLoader.LoadContentAsync );
.