Lars
Lars

Reputation: 776

List of Tasks C#

var tasks = new List<Task>();

for (int i = 0; i < pageCount; i++)
{
    var task = Task.Run(() =>
    {
        worker.GetHouses(currentPage);
    });

    tasks.Add(task);
    currentPage++;
}

Task.WaitAll(tasks.ToArray());

There is something i don't understand.

Whenever i use:

var tasks = new[]
    {
        Task.Run(() => {worker.GetHouses(1);}),
        Task.Run(() => {worker.GetHouses(2);}),
        Task.Run(() => {worker.GetHouses(3);})
    };

And i loop trough that array, i get results perfectly fine. (when using Task.WaitAll(tasks)

When i use:

var tasks = new List<Task>();

my Task.WaitAll(tasks.toArray()) doesn't seem to work, my tasks "Status" stays on "RanToCompletion"

What did i do wrong?

Upvotes: 3

Views: 12752

Answers (2)

alex.b
alex.b

Reputation: 4567

There's been little issue with task types.
In your sample you were using System.Threading.Tasks.Task, which does not have the result - it's intended just to do some job, like void method.
In your code here:

var tasks = new[]
{
    Task.Run(() => {worker.GetHouses(1);}),
    Task.Run(() => {worker.GetHouses(2);}),
    Task.Run(() => {worker.GetHouses(3);})
};

no type were specified explicitly, so it turned out to be System.Threading.Tasks.Task<List<House>>, but first piece of code you specified the System.Threading.Tasks.Task explicitly:

var tasks = new List<Task>();

What you need to use is System.Threading.Tasks.Task<TResult>:

var tasks = new List<Task<List<House>>>();// <- task type specified explicitly 

for (int i = 0; i < pageCount; i++)
{
    var task = Task.Factory.StartNew<List<House>>(() =>// <- task type specified explicitly , though it's mandatory here
    {
        return worker.GetHouses(currentPage);
    });

    tasks.Add(task);
    currentPage++;
}

In similar situations I tend to define types explicitly, so that code becomes clearer to read and as you can see, even to work.

Upvotes: 0

Rico Suter
Rico Suter

Reputation: 11858

You have a synchronization problem with the currentPage variable. Also create tasks with result.

Solution:

var tasks = new List<Task<List<House>>>();

for (int i = 0; i < pageCount; i++)
{
    var currentPageCopy = currentPage; 
    var task = Task.Run(() =>
    {
        return worker.GetHouses(currentPageCopy);
    });

    tasks.Add(task);
    currentPage++;
}

Task.WaitAll(tasks.ToArray());

The problem with your code is that all GetHouses invocations will be called with currentPage + pageCount - 1 as the last value will be used for all method calls...

Upvotes: 4

Related Questions