Reputation: 622
Hello I'm trying to alert the user when all images have been properly deep zoomed and zipped. Each image is asynchronously deep zoomed and zipped and after all images have been successfully deep zoomed and zipped I wish to alert the user with a pop up.
var z = Task.Factory.StartNew(
() =>
{
cr.Create(current_file_name, output);
File.Copy(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\HTMLViewer.html", outputPath + "\\HTMLViewer.html", true);
ZipFile.CreateFromDirectory(outputPath, Directory.GetParent(outputPath) + "\\" + Path.GetFileNameWithoutExtension(current_file_name) + ".zip");
});
var tasks = new[] { z };
var continued = Task.WhenAll(tasks).ContinueWith((antecedent) =>
{
_window.MainDispatcher.BeginInvoke(new Action(
() =>
{
_popUp.PopUpText = "DeepZoom completed";
_popUp.BeginPopUpTimer();
}));
}, TaskContinuationOptions.OnlyOnRanToCompletion);
I used the followed solution as an example : https://stackoverflow.com/questions/12248832/how-to-check-that-all-tasks-have-been-properly-completed#= but I can't seem to get it working. So just to clarify; this code is within a foreach that iterates through a set of images. When all images have been successfully zipped, I want the _popUp.BeginPopUpTimer
method to be invoked.
Upvotes: 2
Views: 2338
Reputation: 457302
How do I invoke method after a task is completed?
Use await
.
Also:
StartNew
; it's dangerous. Use Task.Run
instead.ContinueWith
; it is also dangerous. Use await
instead.BeginInvoke
. Use await
or IProgress<T>
instead.Applying these best practices, the code is considerably simplified:
await Task.Run(() =>
{
cr.Create(current_file_name, output);
File.Copy(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\HTMLViewer.html", outputPath + "\\HTMLViewer.html", true);
ZipFile.CreateFromDirectory(outputPath, Directory.GetParent(outputPath) + "\\" + Path.GetFileNameWithoutExtension(current_file_name) + ".zip");
});
_popUp.PopUpText = "DeepZoom completed";
_popUp.BeginPopUpTimer();
Upvotes: 0
Reputation: 653
Try to use async await
private async Task DoMyWork()
{
var z = Task.Factory.StartNew(
() =>
{
cr.Create(current_file_name, output);
File.Copy(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\HTMLViewer.html", outputPath + "\\HTMLViewer.html", true);
ZipFile.CreateFromDirectory(outputPath, Directory.GetParent(outputPath) + "\\" + Path.GetFileNameWithoutExtension(current_file_name) + ".zip");
});
var tasks = new[] { z };
await Task.WhenAll(tasks);
_window.MainDispatcher.BeginInvoke(() =>
{
_popUp.PopUpText = "DeepZoom completed";
_popUp.BeginPopUpTimer();
});
}
When you have only one task you do not have to use Task.WhenAll
. You can use use:
await Task.Factory.StartNew(
() =>
{
cr.Create(current_file_name, output);
File.Copy(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\HTMLViewer.html", outputPath + "\\HTMLViewer.html", true);
ZipFile.CreateFromDirectory(outputPath, Directory.GetParent(outputPath) + "\\" + Path.GetFileNameWithoutExtension(current_file_name) + ".zip");
});
_window.MainDispatcher.BeginInvoke(() =>
{
_popUp.PopUpText = "DeepZoom completed";
_popUp.BeginPopUpTimer();
});
Upvotes: 3