user4455960
user4455960

Reputation: 49

How to wait for all tasks to be completed

I have a function that has two parts. need all the success of the first part before execute the second part.

Such as:

ConcurrentDictionary<string, string> _dic = new ConcurrentDictionary<string, string>();
var _taskList = new List<Task>();
foreach (var item in someDataList)
{ 
    _taskList.Add(new Task(async () =>
    { 
        var result = await _req.ExecuteAsync(someParams).ConfigureAwait(false);
         _dic.TryAdd(result.data, result.data);
    }
}
_taskList.ForEach(t => t.Start());
await Task.WhenAll(_taskList.ToArray()).ConfigureAwait(false);

if (_dic.Count == List.count()
{
    //execute part 2.
}

not waiting for all tasks to be completed, there is no data in the dictionary at any time. and i try:

 while (true)
{
    foreach (var item in _taskList)
    {
       if (item.Status == TaskStatus.Running)
          goto continueWait;
    }
}


but it didn't work either.

Why is that? What should I do?

Upvotes: 0

Views: 980

Answers (2)

Jaha
Jaha

Reputation: 159

The code below example of async loop

var series = Enumerable.Range(1, 5).ToList();
    var tasks = new List<Task<Tuple<int, bool>>>();
    foreach (var i in series)
    {
        Console.WriteLine("Starting Process {0}", i);
        tasks.Add(DoWorkAsync(i));
    }
    foreach (var task in await Task.WhenAll(tasks))
    {
        if (task.Item2)
        {
            Console.WriteLine("Ending Process {0}", task.Item1);
        }
    }

Upvotes: 0

JohanP
JohanP

Reputation: 5472

There won't be any data in your dict because passing in an async lambda is not going to make any difference in Task's ctor.

You will need to restructure your code quite a bit. You want to call your async method, put the Task in your list and then await till of them complete. Once they're completed, then can you iterate over all your results in your task list and pull out the .Result from it.

var tasks = someDataList.Select(i => _req.ExecuteAsync(i) );
await Task.WhenAll(tasks);
var dict = tasks.ToDictionary(t=> t.Result);
if (dict.Count == List.count()
{
    //execute part 2.
}

Note that if _dict is a global variable and you need locking, then you should just replace ToDictionary with your ConcurrentDictionary code above as this is example code.

Upvotes: 4

Related Questions