Первоначально мой ViewModel было следующее:Постоянное обновление ViewModel от DataService MVVM Light
public ObservableCollection<DataListItem> files { get; private set; }
private object _filesLock = new object();
public MainViewModel(IDataService dataService)
{
files = new ObservableCollection<DataListItem>();
BindingOperations.EnableCollectionSynchronization(files, _filesLock);
_dataService = dataService;
}
Одна из команд побежал этот код
await Task.Run(() => {
Parallel.ForEach(files, new ParallelOptions() { MaxDegreeOfParallelism = 2 }, (file) =>
{
this.files.Add(new DataListItem(file));
});
});
Но это не работает во время разработки. Поэтому я переместил код в DataService.
public async void ScanFolder()
{
if (!CanScanFolder()) return;
files.Clear();
await Task.Run(() =>
{
_dataService.GetData(SelectedFolder, filter, IncludeSubs, (myfiles, error) =>
{
if (error != null)
{
return;
}
foreach (var file in myfiles.files)
{
files.Add(file);
}
}
);
});
}
Код по DataService выглядит следующим образом
public async void GetData(string folder, string filter, bool includeSubs, Action<DataItem, Exception> callback)
{
// Use this to connect to the actual data service
var item = new DataItem(folder, filter, includeSubs);
await item.ScanFolderAsync();
callback(item, null);
}
public async Task<bool> ScanFolderAsync()
{
try
{
var ret = new List<DataListItem>();
var files = Directory.EnumerateFiles(folder, filter, includeSubs ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
await Task.Run(() => {
Parallel.ForEach(files, new ParallelOptions() { MaxDegreeOfParallelism = 2 }, (file) =>
{
this.files.Add(new DataListItem(file));
});
});
return true;
}
catch (Exception)
{
return false;
}
}
Но, насколько я могу сказать, что не существует непрерывного канала связи между DataService и ViewModel. Таким образом, с новым подходом он считывает все файлы, а затем отображает его в сетке, но я хочу, чтобы он отображал каждое обновление по мере его появления.
Моим инстинктом является добавить Messenger в пределах foreach и подписаться на него в ViewModel, но, похоже, не существует способа использовать мессенджер в службе данных.
Как DataService может отправлять сообщение в ViewModel каждый раз, когда он сканирует файл? В качестве альтернативы, есть ли лучшая архитектура для загрузки данных?