공통 포맷으로 각각의 데이터로 변환하고 상기 서비스 층의 각 메소드는 새로운 시작 등UI 스레드를 차단하지 않고 여러 작업을 수행 한 후 어떻게 계속합니까? 제 MVVM 애플리케이션 내보기 모델은, 3 개 개의 다른 서비스 메소드 호출에서
속성 통지/관찰 모음을 이용한 UI를 업데이트 Task
을 입력하고 Task
을 뷰 모델에 반환합니다. 다음은 내 서비스 방법 중 하나의 예입니다.
public class ResourceService
{
internal static Task LoadResources(Action<IEnumerable<Resource>> completedCallback, Action<Exception> errorCallback)
{
var t = Task.Factory.StartNew(() =>
{
//... get resources from somewhere
return resources;
});
t.ContinueWith(task =>
{
if (task.IsFaulted)
{
errorCallback(task.Exception);
return;
}
completedCallback(task.Result);
}, TaskScheduler.FromCurrentSynchronizationContext());
return t;
}
}
여기
private ObservableCollection<DataItem> Data = new ObservableCollection<DataItem>();
public ICollectionView DataView
{
get { return _dataView; }
set
{
if (_dataView != value)
{
_dataView = value;
RaisePropertyChange(() => DataView);
}
}
}
private void LoadData()
{
SetBusy("Loading...");
Data.Clear();
Task[] tasks = new Task[3]
{
LoadTools(),
LoadResources(),
LoadPersonel()
};
Task.WaitAll(tasks);
DataView = CollectionViewSource.GetDefaultView(Data);
DataView.Filter = FilterTimelineData;
IsBusy = false;
}
private Task LoadResources()
{
return ResourceService.LoadResources(resources =>
{
foreach(var r in resources)
{
var d = convertResource(r);
Data.Add(d);
}
},
error =>
{
// do some error handling
});
}
이 거의 작품 ... 호출 코드와 뷰 모델의 다른 관련 부분이다하지만 작은 문제가 몇 가지 있습니다.
번호 1 : 처음에 SetBusy
을 호출 할 때 어떤 작업을 시작하기 전에 WaitAll
을 호출하기 전에 IsBusy
속성을 true로 설정합니다. 이 UI를 업데이트하고 BusyIndicator 컨트롤을 표시해야하지만 작동하지 않습니다. 또한 간단한 문자열 속성을 추가하고 바인딩하려고 시도했지만 업데이트되지 않았습니다. IsBusy 기능은 기본 클래스의 일부이며 하나 이상의 작업이 실행되지 않는 다른보기 모델에서 작동하므로 XAML의 속성 알림 또는 데이터 바인딩에 문제가 있다고 생각하지 않습니다.
전체 데이터 바인딩은 전체 메서드가 완료된 후 업데이트 된 것처럼 보입니다. "처음 예외"또는 UI 스레드가 어떻게 든 WaitAll 호출하기 전에 차단되는 믿을 선도하는 출력 창 바인딩 오류가 표시되지 않습니다.
2 번 : 서비스 방법에서 잘못된 작업을 반환하는 것 같습니다. 보기 모델이 모든 결과를 콜백의 모든 서비스 메소드에서 변환 한 후에 실행하려면 WaitAll
이후의 모든 것을 원합니다. 그러나 서비스 메서드에서 연속 작업을 반환하면 연속이 호출되지 않으며 WaitAll
은 영원히 기다립니다. 이상한 일은 ICollectionView에 바인딩 된 UI 컨트롤이 실제로 모든 것을 올바르게 표시한다는 것입니다. 데이터가 관찰 가능한 컬렉션이고 CollectionViewSource가 컬렉션 변경 이벤트를 인식하고 있기 때문에 이것을 가정했습니다.
WPF 명령과 Prism DelegateCommand로 "그냥 작동하는지"확실하지 않기 때문에 async/await을 사용하지 말았습니다. Task.ContinueWhenAll이 존재하지 않는 것 같습니다. 일부 TPL 확장 라이브러리를 참조해야합니까? – BenCr
@BenCr 죄송합니다 .- 작업의 틀입니다 .ContinueWhenAll. 일반적으로 대기/비동기 작업은 WPF의 작업 계속보다 더 잘 작동합니다. 주요 차이점은 예외를 처리하기 위해 미친 농구를 뛰어 넘을 필요가 없다는 것입니다. –
감사 리드, 이것은 훨씬 더 잘 작동하는 것 같습니다. WaitAll이 호출되기 전에 누군가가 차단에 대한 설명을 제공 할 수 있기를 바랍니다.하지만이 문제는 확실히 1 및 2 문제를 해결했습니다. 다음 반복에서 비동기/대기중인 작업을 수행하고 어떻게 진행되는지 봅니다. – BenCr