Several Points:
- tasks.Add(), use variable capture to "pass in" parameters. If you change the value of variables of a task (for example a iterator in a for loop) it will also change the value inside of the task. For example, in the Example 1 codes, int delayInterval = ctr; instead of use ctr directly.
- Example 2 provides different ways to create task arrays.
- Example 3 is a simple version leverage LINQ.
Example 1:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace SystemTasks
{
public class Example
{
public static void Main()
{
var tasks = new List<Task<long>>();
for (int ctr = 5000; ctr >= 1000; ctr -= 1000)
{
int delayInterval = ctr;
tasks.Add(Task.Run(async () => {
Console.WriteLine("Start " + delayInterval);
// Console.WriteLine(cnti);
long total = 0;
//await Task.Delay(delayInterval);
Thread.Sleep(delayInterval);
var rnd = new Random();
// Generate 1,000 random numbers.
for (int n = 1; n <= 1000; n++)
total += rnd.Next(0, 1000);
Console.WriteLine("Finish " + delayInterval);
return total;
}));
}
var continuation = Task.WhenAll(tasks);
try
{
continuation.Wait();
}
catch (AggregateException)
{ }
if (continuation.Status == TaskStatus.RanToCompletion)
{
long grandTotal = 0;
foreach (var result in continuation.Result)
{
grandTotal += result;
Console.WriteLine("Mean: {0:N2}, n = 1,000", result / 1000.0);
}
Console.WriteLine("\nMean of Means: {0:N2}, n = 10,000",
grandTotal / 10000);
}
// Display information on faulted tasks.
else
{
foreach (var t in tasks)
{
Console.WriteLine("Task {0}: {1}", t.Id, t.Status);
}
}
}
}
}
Example 2:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace SystemTasks
{
class TestTask
{
private async static Task TestAsync()
{
await Task.Delay(1000);
Console.WriteLine("finish async task");
}
private static void TestSync()
{
Thread.Sleep(1000);
Console.WriteLine("finish sync task");
}
private static void TestSyncIth(int ith)
{
Console.WriteLine("Start TestSyncIth " + ith);
Thread.Sleep(1000 * ith);
Console.WriteLine("Finish TestSyncIth " + ith);
}
private async static Task StartAsync(int option)
{
Console.WriteLine("Start to test with option " + option);
List<Task> tasks = new List<Task>();
if (option == 0)
{
for (int i = 5; i >= 1; --i)
{
int ith = i;
tasks.Add(new Task(() => TestSyncIth(ith)));
}
foreach (var task in tasks)
{
task.Start();
}
}
else if (option == 1)
{
// starting a task with async action method 1
var t = new Task<Task>(async () => await TestAsync());
t.Start();
tasks.Add(t.Unwrap());
}
else if (option == 2)
{
// starting a task with async action method 2
var t = Task.Factory.StartNew(async () => await TestAsync());
tasks.Add(t.Unwrap());
}
else
{
// starting a task with async action method 3
tasks.Add(Task.Run(async () => await TestAsync()));
}
await Task.WhenAll(tasks.ToArray());
Console.WriteLine("finish test");
Console.WriteLine("------------------");
}
static void Main()
{
StartAsync(0).ConfigureAwait(false).GetAwaiter().GetResult();
StartAsync(1).ConfigureAwait(false).GetAwaiter().GetResult();
StartAsync(2).ConfigureAwait(false).GetAwaiter().GetResult();
StartAsync(3).ConfigureAwait(false).GetAwaiter().GetResult();
}
}
}
Example 3:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace SystemTasks
{
class TestTask
{
public async static Task TestSyncIth(int ith)
{
Console.WriteLine("Start TestSyncIth " + ith);
//Thread.Sleep(1000 * ith);
await Task.Delay(1000*ith);
Console.WriteLine("Finish TestSyncIth " + ith);
}
public async static Task StartAsync(int option)
{
List<int> nums = new List<int> {5, 4, 3, 2, 1};
var tasks = nums.Select(TestSyncIth).ToArray();
await Task.WhenAll(tasks);
}
static void Main()
{
// StartAsync(0).ConfigureAwait(false).GetAwaiter().GetResult();
//var res1 = StartAsync(0).GetAwaiter();
StartAsync(0).ConfigureAwait(false).GetAwaiter().GetResult();
return;
}
}
}