Saya ingin menanyakan pendapat Anda tentang arsitektur yang benar kapan harus digunakan Task.Run
. Saya mengalami UI lamban dalam aplikasi WPF .NET 4.5 kami (dengan kerangka kerja Caliburn Micro).
Pada dasarnya saya lakukan (cuplikan kode yang sangat sederhana):
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();
}
}
Dari artikel / video yang saya baca / lihat, saya tahu itu await
async
belum tentu berjalan di utas latar dan untuk mulai bekerja di latar belakang Anda harus membungkusnya dengan menunggu Task.Run(async () => ... )
. Menggunakan async
await
tidak memblokir UI, tetapi tetap berjalan di utas UI, sehingga membuatnya tertinggal.
Di mana tempat terbaik untuk meletakkan Task.Run?
Haruskah saya hanya
Bungkus panggilan luar karena ini kurang bekerja threading untuk .NET
, atau haruskah saya membungkus hanya metode terikat CPU yang berjalan secara internal
Task.Run
karena ini membuatnya dapat digunakan kembali untuk tempat lain? Saya tidak yakin di sini jika mulai mengerjakan utas latar belakang jauh di inti adalah ide yang bagus.
Ad (1), solusi pertama akan seperti ini:
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.
Ad (2), solusi kedua akan seperti ini:
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());
seharusnyaawait Task.Run( () => this.contentLoader.LoadContentAsync() );
. AFAIK Anda tidak mendapatkan apa-apa dengan menambahkan sedetikawait
danasync
dalamTask.Run
. Dan karena Anda tidak melewatkan parameter, itu menyederhanakan sedikit lebih banyakawait Task.Run( this.contentLoader.LoadContentAsync );
.