Sample Code:
class Program
{
static void sleepFunc()
{
int before = Thread.CurrentThread.ManagedThreadId;
Thread.Sleep(5000);
int after = Thread.CurrentThread.ManagedThreadId;
Console.WriteLine($"{before} -> sleep -> {after}");
}
static async void delayFunc()
{
int before = Thread.CurrentThread.ManagedThreadId;
await Task.Delay(5000);
int after = Thread.CurrentThread.ManagedThreadId;
Console.WriteLine($"{before} -> delay -> {after}");
}
static void Main(string[] args)
{
List<Thread> threads = new List<Thread>();
for(int i = 0; i < 10; i++)
{
var thread = new Thread(sleepFunc);
thread.Start();
threads.Add(thread);
}
Thread.Sleep(1000); // just to separate the result sections
for (int i = 0; i < 10; i++)
{
var thread = new Thread(delayFunc);
thread.Start();
threads.Add(thread);
}
Console.ReadLine();
}
}
Sample Output:
3 -> sleep -> 3
7 -> sleep -> 7
4 -> sleep -> 4
5 -> sleep -> 5
6 -> sleep -> 6
8 -> sleep -> 8
9 -> sleep -> 9
10 -> sleep -> 10
11 -> sleep -> 11
12 -> sleep -> 12
21 -> delay -> 25
18 -> delay -> 37
15 -> delay -> 36
16 -> delay -> 32
19 -> delay -> 24
20 -> delay -> 27
13 -> delay -> 32
17 -> delay -> 27
22 -> delay -> 25
14 -> delay -> 26
The continuation for Thread.Sleep() runs on the same explicitly created thread, but the continuation for Task.Delay() runs on a different (thread pool) thread.
Since the continuation always runs on the thread pool, is it just pointless/wasteful/antipattern to use a new Thread(func) if there is an await anywhere inside the func? Is there any way to force a task to continue on the original non-thread-pool new thread?
I'm asking because I read someone recommending to put a long running loop (for socket communication for example) in a Thread instead of in a Task, but it seems that if they call ReadAsync then it ends up being a Task on the thread pool anyway, and the new Thread was pointless?