Ursprünglich mein Ansichtsmodell hatte folgende:Kontinuierliche Aktualisierung des Ansichtsmodelles von Data MVVM Licht
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;
}
Einer der Befehle lief diesen Code
await Task.Run(() => {
Parallel.ForEach(files, new ParallelOptions() { MaxDegreeOfParallelism = 2 }, (file) =>
{
this.files.Add(new DataListItem(file));
});
});
Aber diese zur Design-Zeit nicht funktioniert. Also habe ich den Code in den DataService verschoben.
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);
}
}
);
});
}
Der Data Code sieht wie folgt aus
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;
}
}
Aber soweit ich das beurteilen kann, gibt es keine kontinuierliche Kommunikationskanal zwischen dem Dataservice und der Ansichtsmodell. Mit dem neuen Ansatz liest es also alle Dateien und zeigt sie dann im Raster an, aber ich möchte, dass jedes Update so angezeigt wird, wie es läuft.
Mein Instinkt ist es, einen Messenger innerhalb der Foreach hinzuzufügen und im ViewModel zu abonnieren, aber es scheint keinen Weg zu geben, einen Messenger in einem Datendienst zu verwenden.
Wie kann der DataService jedes Mal, wenn er eine Datei gescannt hat, eine Nachricht an das ViewModel senden? Gibt es alternativ eine bessere Architektur zum Laden der Daten?