MVVM 中的后台线程进度通知?

发布于 2024-12-02 04:06:15 字数 900 浏览 0 评论 0原文

如何修改 MVVM 视图模型 Progress 属性以在后台线程上完成工作?

我正在创建一个 MVVM 应用程序,它使用 Task.Factory.StartNew()Parallel.ForEach() 在后台线程上执行任务。我使用这篇文章作为指南。到目前为止,我的代码如下所示:

Task.Factory.StartNew(() => DoWork(fileList, viewModel));

其中 fileList 是要处理的文件列表,viewModel 是带有 Progress 的视图模型财产。到目前为止,DoWork() 方法如下所示:

private object DoWork(string[] fileList, ProgressDialogViewModel viewModel)
{
    Parallel.ForEach(fileList, imagePath => ProcessImage(imagePath));
}

ProcessImage() 方法执行实际的图像处理。视图模型的 Progress 属性绑定到在后台进程开始之前显示的对话框中的进度条。

我想在每次迭代 Parallel.ForEach() 语句后更新视图模型 Progress 属性。我需要做的就是增加属性值。我该怎么做?感谢您的帮助。

How do I modify an MVVM view model Progress property for work being done on a background thread?

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));

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));
}

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.

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

笑饮青盏花 2024-12-09 04:06:15

由于该属性是一个简单属性(而不是集合),因此您应该能够直接设置它。 WPF 将自动处理返回 UI 线程的封送处理。

但是,为了避免竞争条件,您需要显式处理“完成”计数器的递增。这可能是这样的:

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;
       }
}

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;
       }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文