- Thread.Sleep and non-Async method will block the thread
- await Task.Delay or await Async method will delay the task, but won’t block the thread. The usage of thread will be handed over to other tasks.
- By default, the system has 4 threads, but may run 60 tasks in parallel. So the following codes will finish in 1 sec using Task.Delay, but more time using Thread.Sleep.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace SystemTasks
{
class TestTask
{
public async static Task<long> TestSyncIth(int ith)
{
Console.WriteLine("Start TestSyncIth " + ith);
Thread.Sleep(1000); //Could not finish in 1 sec
//await Task.Delay(1000); //Finish in 1 sec
Console.WriteLine("Finish TestSyncIth " + ith);
return ith;
}
public async static Task StartAsync(int option)
{
List<int> nums = new List<int>();
for (int i = 60; i >= 1; --i)
nums.Add(i);
var tasks = nums.Select(TestSyncIth).ToArray();
await Task.WhenAll(tasks);
foreach(var cur in tasks)
{
if (cur.Status == TaskStatus.RanToCompletion)
{
long res = cur.Result;
Console.WriteLine("StartAsync " + res);
}
}
Console.WriteLine("All Finish");
}
static void Main()
{
StartAsync(0).ConfigureAwait(false).GetAwaiter().GetResult();
return;
}
}
}
Several strategies to improve the above non-async codes:
- threadpool.setminthreads
- Codes like the following:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace SystemTasks
{
class TestTask
{
public async static Task<long> TestSyncIth(int ith)
{
Console.WriteLine("Start TestSyncIth " + ith);
Thread.Sleep(1000); //Could not finish in 1 sec
//await Task.Delay(1000); //Finish in 1 sec
Console.WriteLine("Finish TestSyncIth " + ith);
return ith;
}
public async static Task StartAsync(int option)
{
var tasks = new List<Task<long>>();
for (int i = 60; i >= 1; --i)
{
int cur = i;
var t = Task.Factory.StartNew(async () => await TestSyncIth(cur), TaskCreationOptions.LongRunning);
tasks.Add(t.Unwrap());
}
await Task.WhenAll(tasks);
foreach(var cur in tasks)
{
if (cur.Status == TaskStatus.RanToCompletion)
{
long res = cur.Result;
Console.WriteLine("StartAsync " + res);
}
}
Console.WriteLine("All Finish");
}
static void Main()
{
StartAsync(0).ConfigureAwait(false).GetAwaiter().GetResult();
return;
}
}
}
A more simpler example:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace SystemTasks
{
class TestTask
{
public static void TestIth(int ith)
{
Console.WriteLine("Start TestSyncIth " + ith);
Thread.Sleep(2000);
Console.WriteLine("Finish TestSyncIth " + ith);
}
static void Main()
{
List<int> list = new List<int>() {1, 2, 3, 4, 5};
Parallel.ForEach(list, item => TestIth(item));
return;
}
}
}