(с инфраструктурой Caliburn Micro).
В основном я так и делаю (очень упрощенные фрагменты кода):< /p>
public class PageViewModel : IHandle
{
...
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();
}
}
Из статей/видео, которые я читал/видел, я знаю, что await async не обязательно выполняется в фоновом потоке и для начала работы в фоновом режиме вам нужно обернуть его await Task.Run(async () => ... ). Использование async await не блокирует пользовательский интерфейс, но по-прежнему выполняется в потоке пользовательского интерфейса, что приводит к его задержке.
Где лучшее место для размещения Task.Run?
Должен ли я просто
- Заверните внешний вызов, потому что для .NET требуется меньше потоков
- , или мне следует обернуть только методы, связанные с ЦП, которые выполняются внутри Task.Run , поскольку это делает его пригодным для повторного использования в других местах? Я не уверен, что начинать работу над фоновыми потоками глубоко в ядре — хорошая идея.
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.
Объявление (2), второе решение будет таким:
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
}
Подробнее здесь: https://stackoverflow.com/questions/180 ... sync-await