继续执行多项任务
我正在使用 TPL 在 MVVM 应用程序的后台线程上串行执行两个任务。任务运行时,应用程序会显示“进度”对话框。因此,我的 MVVM 命令的 Execute() 方法首先在主视图模型中引发一个 ImageProcessingStarting 事件。视图通过显示“进度”对话框来响应事件。然后,该命令启动第一个任务,继续执行第二个任务,并通过在主视图模型中引发 ImageProcessingEnding
事件来执行最终的“继续”。视图通过关闭“进度”对话框来响应该事件。代码如下。
两个后台任务都正常执行,但“进度”对话框在第一个任务完成后(而不是第二个任务完成后)提前关闭。我希望有人能告诉我原因以及如何解决这个问题。感谢您的帮助。
public void Execute(object parameter)
{
...
// Announce that image processing is starting
m_ViewModel.RaiseImageProcessingStartingEvent();
// Set up a cancellation token source
var tokenSource = new CancellationTokenSource();
m_ViewModel.ProgressDialogViewModel.TokenSource = tokenSource;
// Background Task #1: Add time stamps to files
var task = Task.Factory.StartNew(() => this.AddTimeStampsToFiles(fileList, progressDialogViewModel));
/* The Progress dialog is closing at this point! */
// Background Task #2: Resequence files
task.ContinueWith(t => this.ResequenceFiles(fileList, progressDialogViewModel));
/* The Progress dialog should close at this point. */
// Announce that image processing is finished
task.ContinueWith(t => m_ViewModel.RaiseImageProcessingEndingEvent(), TaskScheduler.FromCurrentSynchronizationContext());
}
I am using TPL to perform two tasks serially on a background thread in an MVVM app. While the tasks are running, the app displays a Progress dialog. So, my MVVM command's Execute()
method first raises an ImageProcessingStarting
event in the main view model. The view responds to the event by displaying the Progress dialog. The command then launches the first task, continues with the second task, and performs the final 'continue with' by raising an ImageProcessingEnding
event in the main view model. The view responds to the event by closing the Progress dialog. The code is below.
Both background tasks are executing properly, but the Progress dialog is closing early, after the first task completes, instead of after the second one. I am hoping someone can tell me why, and how to fix the problem. Thanks for your help.
public void Execute(object parameter)
{
...
// Announce that image processing is starting
m_ViewModel.RaiseImageProcessingStartingEvent();
// Set up a cancellation token source
var tokenSource = new CancellationTokenSource();
m_ViewModel.ProgressDialogViewModel.TokenSource = tokenSource;
// Background Task #1: Add time stamps to files
var task = Task.Factory.StartNew(() => this.AddTimeStampsToFiles(fileList, progressDialogViewModel));
/* The Progress dialog is closing at this point! */
// Background Task #2: Resequence files
task.ContinueWith(t => this.ResequenceFiles(fileList, progressDialogViewModel));
/* The Progress dialog should close at this point. */
// Announce that image processing is finished
task.ContinueWith(t => m_ViewModel.RaiseImageProcessingEndingEvent(), TaskScheduler.FromCurrentSynchronizationContext());
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
根据 MSDN
这意味着当主要任务完成时,两个ContinueWith 调用中的其他项目将并行运行。
为了演示这一点,您可以使用下面的代码:
然后输出窗口将显示:
为了帮助您解决问题,我一直使用 System.ComponentModel.BackgroundWorker 来串行运行任务。可能有更好的方法,但这目前对我有用。
为此,您可能需要将
fileList
和progressDialogViewModel
值传递到bgW.RunWorkerAsync()
方法。对于多个值,我通常使用
Dictionary
对象,这样我就可以按名称引用值。希望这有帮助。
According to MSDN
Which means that when the main task finishes, the other items in your two ContinueWith calls will run in parallel with one another.
To demonstrate this, you use the code below:
The Output Window will then read:
To help you out in your question, I have always used the
System.ComponentModel.BackgroundWorker
to run tasks serially. There are probably better ways, but this works for me for now.For this to work, you may need to pass the
fileList
andprogressDialogViewModel
values in to thebgW.RunWorkerAsync()
method.For multiple values, I typically use a
Dictionary<string, object>
object so I can refer to the values by name.Hope this helps.
找到了我的答案。在我的原始代码中,第二个和第三个任务都是第一个任务的延续。我更改了代码,为原始任务 (
taskOne
) 和延续任务(taskTwo
和taskThree
)创建单独的任务。然后,taskTwo
继续taskOne
,taskThree
继续taskTwo
,就像这样:我已经接受了胖子的回答,因为它确实提供了一个可行的替代方案。然而,我在我的应用程序中使用了这个答案中的方法,因为我使用的是 TPL。
Found my answer. In my original code, both the second and third tasks were continuations of the first task. I changed my code to create separate tasks for the original task (
taskOne
) and the continuation tasks (taskTwo
andtaskThree
). Then,taskTwo
continuestaskOne
, andtaskThree
continuestaskTwo
, like this:I have accepted Fatty's answer, since it does present a viable alternative. However, I am using the approach in this answer in my application, since I am using TPL.