Reputation: 2748
I have a loop that creates multiple tasks as shown below. How do I update the screen (add a new line to a textbox with some data) as each task completes?
How do I detect when all tasks are complete?
C# Code
for (int i = 0; i < int.Parse(radTextBoxFloodRequests.Text); i++)
{
int x = i;
// Create a task and supply a user delegate by using a lambda expression.
var taskA = new Task(() => TaskRequest(int.Parse(radTextBoxFirstNumber.Text), int.Parse(radTextBoxSecondNumber.Text), int.Parse(radTextBoxFloodDelay.Text), x));
// Start the task.
taskA.Start();
}
private void TaskRequest(int number1, int number2, int delay, int count)
{
// Some long running method
}
Upvotes: 16
Views: 24855
Reputation: 1390
Expanding on User 12345678's answer, you could do something like the below.
private void RunTasks()
{
Dictionary<string, string> dict = new Dictionary<string, string>();
List<Task> tasks = new List<Task>();
foreach (KeyValuePair<string,string> kvp in dict)
{
Console.WriteLine("Executing task " + kvp.Key + " ...");
Task t = new Task(() => MyMethod(kvp.Key, kvp.Value));
tasks.Add(t);
t.Start();
t.ContinueWith(task => Console.WriteLine(kvp.Key + " completed"));
}
Console.WriteLine("Waiting tasks to complete...");
Task.WaitAll(tasks.ToArray());
Console.WriteLine("All tasks completed...");
}
private void MyMethod(string arg1, string arg2)
{
}
Upvotes: 1
Reputation: 7804
You can use ContinueWith()
:
"Creates a continuation that executes asynchronously when the target Task completes." - MSDN
Task t = new Task(() => Console.WriteLine("")).ContinueWith(task => Console.Writeline("Continue With"),
TaskScheduler.FromCurrentSynchronizationContext());
Upvotes: 21
Reputation: 14972
Are you looking for Parallel.ForEach()
?
[Test]
public void ParallelTasks()
{
var strings = new List<string> {"task1", "task2", "task3"};
Parallel.ForEach(strings, str => Console.WriteLine(str + "is done"));
// All your parallel tasks are executed now
}
Upvotes: 1
Reputation: 65304
I recommend you use a combination of 3 simple constructs:
int numActiveTasks
, that is incremented with InterlockedIncrement(ref numActiveTasks)
on task creation, i.e. immediately before taskA.Start()
and decremented with InterlockedDecrement(ref numActiveTasks)
at the end of the task, i.e. at the end of the function TaskRequest(...)
ManualResetEvent
, that is reset before task start and signalled on task end after the counter decrementWaitOne()
s on the ManualResetEvent
, then reads numActiveTasks
This gives you
The main advantage of this is, that you have souvereignity about on which thread the notification occurs.
Upvotes: 1