最初,我的ViewModel有以下内容:
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,并在ViewModel中订阅它,但是似乎没有一种在数据服务中使用信使的方法。
DataService如何在每次扫描文件时向ViewModel发送消息?或者,是否有一个更好的架构来加载数据?
发布于 2016-05-18 15:00:24
原来我只是遗漏了信使的using语句,可以使用它来更新ViewModel。
在我添加的ViewModel构造函数中
Messenger.Default.Register<DataListItem>(this, (item) => { files.Add(item); });更新ScanFolderAsync()方法以发送消息
using GalaSoft.MvvmLight.Messaging;
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 = 1 }, (file) =>
{
var item = new DataListItem(file);
Messenger.Default.Send<DataListItem>(item);
this.files.Add(item);
});
});
return true;
}
catch (Exception)
{
return false;
}
}https://stackoverflow.com/questions/37303188
复制相似问题