올바른 아키텍처에 대한 의견을 묻고 싶습니다 Task.Run
. WPF .NET 4.5 응용 프로그램 (Caliburn Micro 프레임 워크 사용)에서 느린 UI가 발생합니다.
기본적으로 나는 (매우 단순화 된 코드 스 니펫) :
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();
}
}
내가 읽거나 본 기사 / 비디오 await
async
에서 백그라운드 스레드에서 실행되고 있지 않고 백그라운드에서 작업을 시작하기 위해 대기 중으로 래핑해야한다는 것을 알고 있습니다 Task.Run(async () => ... )
. 를 사용 async
await
하면 UI가 차단되지 않지만 여전히 UI 스레드에서 실행 중이므로 지연됩니다.
Task.Run을 놓을 가장 좋은 곳은 어디입니까?
그냥해야 할까
.NET의 스레딩 작업이 적기 때문에 외부 호출을 래핑하십시오.
또는 내부에서 실행되는 CPU 바인딩 메소드 만 랩핑해야
Task.Run
다른 장소에서 재사용 할 수 있습니까? 코어의 깊은 백그라운드 스레드에서 작업을 시작하는 것이 좋은 아이디어인지 확실하지 않습니다.
광고 (1)에서 첫 번째 해결책은 다음과 같습니다.
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
}
await Task.Run(async () => await this.contentLoader.LoadContentAsync());
은 단순히이어야await Task.Run( () => this.contentLoader.LoadContentAsync() );
합니다. AFAIK 당신은 초await
와async
내부를 추가하여 아무것도 얻지 못합니다Task.Run
. 그리고 매개 변수를 전달하지 않기 때문에 약간 더 단순화됩니다await Task.Run( this.contentLoader.LoadContentAsync );
.