【发布时间】:2013-12-24 18:06:32
【问题描述】:
我在 VS2012,WPF 和 MVVM 中做一些 TPL。我有一个问题,我想我知道答案,但我想确定。考虑一下这个 sn-p:
TaskCanceller = new CancellationTokenSource();
TaskLoader = Task<object>.Factory.StartNew(() =>
{
//Test the current query
DataRepository dr = new DataRepository(DataMappingSelected);
string test = dr.TestMappingConnection();
if (test.IsNotNullEmpty())
throw new DataConnectionException(test);
//Create the CSV File
DataQueryCsvFile CsvFile = new DataQueryCsvFile();
CsvFile.FileName = IO.Path.GetFileName(FilePath);
CsvFile.FilePath = IO.Path.GetDirectoryName(FilePath);
CsvFile.DataMapping = DataMappingSelected;
CsvFile.DataBrowserQuery = DataQueryHolder;
//Allow for updates to the UI
CsvFile.PageExportComplete += (s, e) =>
{
if (TaskCanceller.IsCancellationRequested)
(s as DataQueryCsvFile).IsSaveCancellationRequested = true;
StatusData = String.Format("{0} of {1} Complete", e.ProgressCount, e.TotalCount);
StatusProgress = (100 * e.ProgressCount / e.TotalCount);
};
CsvFile.SaveFile();
return CsvFile;
});
我有一个 DataQueryCsvFile 类。它的目的是根据一组传递的查询参数创建一个 CSV 文本文件,其结果可能非常大。因此导出“分页”查询生成的表,因此它不会破坏用户的内存。它的成员中有一个名为 PageExportComplete 的事件,每当将“页面”写入文件时都会调用该事件 - 例如一次 1000 条记录。下面的代码使用此事件来更新 UI 上的进度指示器。
进度指示器(StatusData 和 StatusProgress)在 VM 中声明,并带有适当的通知,以便让视图知道它们何时发生更改。例如:
public string StatusData
{
get { return _StatusData; }
set { NotifySetProperty(ref _StatusData, value, () => StatusData); }
}
private string _StatusData;
这是我的问题 - 按原样,这非常有效。但是为什么因为我没有在 ContinueWith 中声明要通过 UI 线程 (FromCurrentSynchronizationContext) 运行或更新的任务。
是因为 MVVM 模式吗?换句话说,因为正在更新的属性是虚拟机本地的,并且因为它们具有更新视图的通知,并且由于通过绑定而失去耦合,所以它的工作原理?还是我只是运气好,我应该通过声明 ContinueWith 来更新 UI 线程的进度?
【问题讨论】:
标签: c# wpf multithreading events mvvm