Ricardo Polo Jaramillo
Ricardo Polo Jaramillo

Reputation: 12318

Process results of tasks in Foreach c#

I was looking for this and I couldn't figure how to do it.

I have a some threats (tasks) in an App.

    foreach (string targetMachine in targetMachines)
    {
        Task<int> task = Task.Run(() => Magic(targetMachine));
    }

I created a task for every object in an array. The task returns a value. I want to process the values and act based on them. As example, if task return 0 dont do anything, if returns 1 write a log, if returns 2 run a process.

How can I acoomplish this? If I process the return values inside the foreach:

foreach (string targetMachine in targetMachines)
    {
        Task<int> task = Task.Run(() => Magic(targetMachine));
        Task.Waitforexit()
        if (task.result == 2)
        {
        do something
        }
    }

I think, task are not going to be useful and the programa will wait each task to be completed to continue.

Upvotes: 0

Views: 2704

Answers (3)

L.B
L.B

Reputation: 116158

It can be something like this:

foreach (string targetMachine in targetMachines)
{
    Task.Run(() =>
    {
        var result = Magic(targetMachine);
        if (result == 2)
        {
            DoSomething();
        }
    });
}

OR (using async/await)

foreach (string targetMachine in targetMachines)
{
    var result = await Task.Run(() => Magic(targetMachine));
    if (result == 2)
    {
        DoSomething();
    }
}

OR (using ContinueWith)

foreach (string targetMachine in targetMachines)
{
    Task<int>.Run(()=>Magic(targetMachine))
        .ContinueWith(t =>
        {
            if (t.Result == 2)
            {
                DoSomething();
            }
        });
}

If you want to wait to finish all of your tasks

Parallel.ForEach(targetMachines, targetMachine =>
{
    var result = Magic(targetMachine);
    if (result == 2)
    {
        DoSomething();
    }
});

Upvotes: 2

usr
usr

Reputation: 171206

I'll add a new variant in addition to the variants given in L.B.'s answer:

var tasks = targetMachines.Select(x => Magic(x));
Task.WaitAll(tasks); //fork-join

If you're using async, you can write:

var tasks = targetMachines.Select(x => Magic(x));
await Task.WhenAll(tasks); //fork-join

And instead of

var tasks = targetMachines.Select(x => Magic(x));

you can always write:

var tasks = targetMachines.Select(x =>
{
    var result = Magic(x);
    if (result == 2) DoSomething();
});

which liberates you from having to use ContinueWith.

Upvotes: 0

Mark Vickery
Mark Vickery

Reputation: 1955

Have a look at Task.ContinueWith()

http://msdn.microsoft.com/en-us/library/dd321405.aspx

When each task is complete it passes the result to the ContinueWith which can then either do nothing, log or call a method like you want.

Additionally you could run the foreach .AsParallel() and remove the tasks altogether.

http://msdn.microsoft.com/en-us/library/dd413602.aspx

Upvotes: 2

Related Questions