Paludan
Paludan

Reputation: 622

How do I invoke method after a task is completed?

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

Answers (2)

Stephen Cleary
Stephen Cleary

Reputation: 457302

How do I invoke method after a task is completed?

Use await.

Also:

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

Kedrzu
Kedrzu

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

Related Questions