在MVVM后台线程进度通知?
我如何修改MVVM视图模型进度
工作性质正在后台线程做了什么?
How do I modify an MVVM view model Progress
property for work being done on a background thread?
我创建一个MVVM应用程序,在后台线程执行一个任务,使用 Task.Factory.StartNew()
和 Parallel.ForEach()
。我使用这篇文章作为指南。到目前为止,我的代码看起来是这样的:
I am creating an MVVM app that executes a task on a background thread, using Task.Factory.StartNew()
and Parallel.ForEach()
. I am using this article as a guide. So far, my code looks like this:
Task.Factory.StartNew(() => DoWork(fileList, viewModel));
其中,的fileList
是一个文件到列表进行处理,而视图模型
与进度
属性视图模型。在的DoWork()
方法看起来是这样的,到目前为止:
Where fileList
is a list of files to be processed, and viewModel
is the view model with the Progress
property. The DoWork()
method looks like this, so far:
private object DoWork(string[] fileList, ProgressDialogViewModel viewModel)
{
Parallel.ForEach(fileList, imagePath => ProcessImage(imagePath));
}
的
processImage来()
方法执行实际的图像处理。视图模型的进度
属性绑定到显示的后台进程开始之前在对话框的进度条。
The ProcessImage()
method does the actual image processing. The view model's Progress
property is bound to a progress bar in a dialog that is displayed just before the background process begins.
我想更新视图模型进度
的 Parallel.ForEach()
语句的每次迭代后财产。所有我需要做的是增加的属性值。我怎么做?感谢您的帮助。
I'd like to update the view model Progress
property after each iteration of the Parallel.ForEach()
statement. All I need to do is increment the property value. How do I do that? Thanks for your help.
由于属性是一个简单的属性(而不是集合),你应该能够设置它直接。 WPF会自动处理的编组回UI线程。
Since the property is a simple property (and not a collection), you should be able to set it directly. WPF will handle the marshaling back to the UI thread automatically.
然而,为了避免出现竞争状况,你需要处理你的完成递增反击明确。这可能是这样的:
However, in order to avoid a race condition, you'll need to handle the incrementing of your "done" counter explicitly. This could be something like:
private object DoWork(string[] fileList, ProgressDialogViewModel viewModel)
{
int done; // For proper synchronization
Parallel.ForEach(fileList,
imagePath =>
{
ProcessImage(imagePath));
Interlocked.Increment(ref done);
viewModel.Progress = done;
}
}