Je travaille sur une application MVVM qui exécute plusieurs tâches en arrière-plan, en utilisant TPL. Les tâches doivent signaler leur progression à l'interface utilisateur afin qu'une boîte de dialogue de progression puisse être mise à jour. Puisque l'application est MVVM, la boîte de dialogue de progression est liée à une propriété du modèle de vue nommée Progress, qui est mise à jour par une méthode du modèle de vue avec la signature UpdateProgress(int increment)
. Les tâches d'arrière-plan doivent appeler cette méthode pour signaler leur progression.
J'utilise une méthode pour mettre à jour la propriété parce qu'elle permet à chaque tâche d'incrémenter la propriété Progress de différentes quantités. Ainsi, si j'ai deux tâches et que la première prend quatre fois plus de temps que la seconde, la première tâche appelle la méthode UpdateProgress(4)
et la seconde tâche appelle UpdateProgress(1)
. Ainsi, la progression est de 80 % lorsque la première tâche est terminée, et de 100 % lorsque la deuxième tâche est terminée.
Ma question est en fait assez simple : Comment appeler la méthode du modèle de vue à partir de mes tâches d'arrière-plan ? Le code est ci-dessous. Merci pour votre aide.
Les tâches utilisent Parallel.ForEach()
dans un code qui ressemble à celui-ci :
private void ResequenceFiles(IEnumerable<string> fileList, ProgressDialogViewModel viewModel)
{
// Wrap token source in a Parallel Options object
var loopOptions = new ParallelOptions();
loopOptions.CancellationToken = viewModel.TokenSource.Token;
// Process images in parallel
try
{
Parallel.ForEach(fileList, loopOptions, sourcePath =>
{
var fileName = Path.GetFileName(sourcePath);
if (fileName == null) throw new ArgumentException("File list contains a bad file path.");
var destPath = Path.Combine(m_ViewModel.DestFolder, fileName);
SetImageTimeAttributes(sourcePath, destPath);
// This statement isn't working
viewModel.IncrementProgressCounter(1);
});
}
catch (OperationCanceledException)
{
viewModel.ProgressMessage = "Image processing cancelled.";
}
}
La déclaration viewModel.IncrementProgressCounter(1)
ne lève pas d'exception, mais ne parvient pas à atteindre le fil d'exécution principal. Les tâches sont appelées depuis MVVM ICommand
dans un code qui ressemble à celui-ci :
public void Execute(object parameter)
{
...
// Background Task #2: Resequence files
var secondTask = firstTask.ContinueWith(t => this.ResequenceFiles(fileList, progressDialogViewModel));
...
}