Ivan Glasenberg
Ivan Glasenberg

Reputation: 29950

Does await Task.Delay(1000) inside new Task() block some thread?

I have read some docs, and what I learned is that await Task.Delay(1000) does not block thread.

But in this code example, it seems that it blocks threads:

       var task = new Task(async () => {
                Console.WriteLine(" ====== begin Delay()");
                for (int i = 1; i < 5; i++)
                {
                    Console.WriteLine(" ===Delay=== " + i);
                    Console.WriteLine("the task thread id: " + Thread.CurrentThread.ManagedThreadId + "; the task id is: " + Task.CurrentId);
                    await Task.Delay(1000);
                    Console.WriteLine("**ddd***:"+i);
                }

                Console.WriteLine(" ====== end Delay()");

            });

            task.Start();

it prints:

 ====== begin Delay()
 ===Delay=== 1
the task thread id: 3; the task id is: 1
**ddd***:1
 ===Delay=== 2
the task thread id: 4; the task id is:
**ddd***:2
 ===Delay=== 3
the task thread id: 3; the task id is:
**ddd***:3
 ===Delay=== 4
the task thread id: 4; the task id is:
**ddd***:4
 ====== end Delay()

as per the print out, it executes the code in a sync way.

I thought it would print some thing like below:

 ====== begin Delay()
 ===Delay=== 1
the task thread id: 3; the task id is: 1    
 ===Delay=== 2
the task thread id: 4; the task id is:    
 ===Delay=== 3
the task thread id: 3; the task id is:    
 ===Delay=== 4
the task thread id: 4; the task id is:    
**ddd***:1
**ddd***:2
**ddd***:3
**ddd***:4
 ====== end Delay()

So I'm confused, could somebody please explain the behavior? Thanks.

Upvotes: 0

Views: 218

Answers (1)

Stephen Cleary
Stephen Cleary

Reputation: 456437

inside new Task()

First, I have to say: never, ever use the Task constructor. There are exactly zero valid use cases. If you want to run a delegate on a thread pool thread, use Task.Run.

So I'm confused, could somebody please explain the behavior?

Yes, the key is that there's a difference between "imperative" (one step after another) and "synchronous" (blocking the caller).

as per the print out, it executes the code in a sync way.

No, it is not synchronous at all. It is, however, imperative. When an await decides it needs to wait, it will "pause" its current method and return to the caller. When that await is ready to continue, it will resume executing its method.

Note that the thread is not blocked. The method is paused. So it is imperative but not synchronous.

Upvotes: 4

Related Questions