Reputation: 1092
I'm struggling with making my tasks run. I believe they don't start and await never returns, that way my application never runs further. It's meant to process multiple data sets (known at the moment of execution) and therefore I add them using a loop, it looks this way:
foreach(IGrouping<enumType, Item> group in lp)
{
Task<ProcessedItem> t = new Task<ProcessedItem>(
() => ProcessItems(group.ToList(), group.Key));
tasks.Add(t);
}
await Task.WhenAll(tasks);
(...)
And it stops at Task.WhenAll. I think they're not started at all, I have a similar code within another method, but there I pass the function to the task directly:
Task<ReturnType>(Func);
Which I believe causes the difference, I cannot pass it this way here due to parameters. How should I modify my code to make it work? Should I explicitly start each task? Wouldn't that break the await keyword if tasks finishes before the await?
Upvotes: 1
Views: 975
Reputation: 149646
I think they're not started at all
You are most certainly correct. new Task()
returns a "cold task", which is a task that hasn't started making you explicitly call Task.Start()
on it. The docs spell this out clearly:
Rather than calling this constructor, the most common way to instantiate a Task object and launch a task is by calling the static
Task.Run(Action)
orTaskFactory.StartNew(Action)
method. The only advantage offered by this constructor is that it allows object instantiation to be separated from task invocation.
This is one of the reasons why you shouldn't use the Task
constructor, and instead use the factory methods, that provide you with a "hot task" which is one that is already started. Here, Task.Run
would be appropriate:
var tasks = lp.Select(group => Task.Run(() => ProcessItems(group.ToList(), group.Key)));
await Task.WhenAll(tasks);
Upvotes: 6
Reputation: 68685
For Starting you need to call Start()
method.And your method in which you use this fragment must be assigned with async
keyword
foreach(IGrouping<enumType, Item> group in lp)
{
Task<ProcessedItem> t = new Task<ProcessedItem>(() => ProcessItems(group.ToList(), group.Key));
t.Start();
tasks.Add(t);
}
await Task.WhenAll(tasks);
(...)
It will wait when all tasks inside then tasks
will finish their exection
Or you can use instead of Start()
method Task.Run()
method
foreach(IGrouping<enumType, Item> group in lp)
{
Task<ProcessedItem> t = Task.Run(() => ProcessItems(group.ToList(), group.Key));
tasks.Add(t);
}
await Task.WhenAll(tasks);
(...)
Upvotes: 3