C# Async function showing different thread id

T.Zacks 3,991 Reputation points
2022-08-30T09:57:06.887+00:00

i am calling async and sync function. when async call then thread id shows 1 and sync function also show thread id 1 but when async function close to end then thread id shows different one why ?

see the code from text file
236006-async-code.txt

await Task.Delay(10000); is causing to show different thread id? if yes then why.....please explain which help me to understand.

please tell me why thread id is getting different one? i heard async function does not spawn any new thread.

Thanks

C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,935 questions
0 comments No comments
{count} votes

3 answers

Sort by: Most helpful
  1. AgaveJoe 28,371 Reputation points
    2022-08-30T11:07:41.457+00:00

    It is true that the async/await keywords do not create a new thread. However, a thread is needed to execute the remaining code which is exactly what happens in the code. Notice the thread Id is the same Id at the start of GetTaskOfTResultAsync(). It changes after the await.

    static void Main(string[] args)  
    {  
        Test().GetAwaiter().GetResult();  
    }  
      
    static async Task Test()  
    {  
        Console.WriteLine("Test thread id " + Thread.CurrentThread.ManagedThreadId);  
        Task<int> returnedTaskTResult = GetTaskOfTResultAsync();  
        SynchronousTask();  
        int intResult = await returnedTaskTResult;  
        Console.WriteLine("Test thread Id " + Thread.CurrentThread.ManagedThreadId);  
    }  
      
    static async Task<int> GetTaskOfTResultAsync()  
    {  
        int hours = 10;  
        Console.WriteLine("GetTaskOfTResultAsync start thread id " + Thread.CurrentThread.ManagedThreadId);  
        await Task.Delay(2000);  
        Console.WriteLine("GetTaskOfTResultAsync end thread id " + Thread.CurrentThread.ManagedThreadId);  
      
        return hours;  
    }  
      
    static void SynchronousTask()  
    {  
        Console.WriteLine("SynchronousTask start thread id " + Thread.CurrentThread.ManagedThreadId);  
        Console.WriteLine("SynchronousTask end thread id " + Thread.CurrentThread.ManagedThreadId);  
    }  
    

    Results

    Test thread id 1  
    GetTaskOfTResultAsync start thread id 1  
    SynchronousTask start thread id 1  
    SynchronousTask end thread id 1  
    GetTaskOfTResultAsync end thread id 4  
    Test thread Id 4  
    
    1 person found this answer helpful.

  2. AgaveJoe 28,371 Reputation points
    2022-08-30T19:02:09.113+00:00

    you mean to say await creating another thread to execute this one returnedTaskTResult ?

    No. I mean exactly what I wrote.

    not clear properly from your explanation. please be elaborate. thanks

    The official Task asynchronous programming model (TAP) documentation does an excellent job illustrating what happens in an asynchronous method. Read the official documentation.

    Background:
    Asynchronous programming has been around a very long time and it has always been very difficult to organize the code. There was an asynchronous caller, an asynchronous response handlers, code to run while waiting for the response, handling any data returned within the asynchronous response handler and using the result in the code. The Task asynchronous programming model (TAP) simplifies the code developers write while the compiler hides the complexity of asynchronous programming.

    Briefly:
    When the main thread hits your GetTaskOfTResultAsync method it just keeps on going until is comes to point where it has nothing else to do which is usually the last await in the chain of async/awaits or the end of a method if there's no await. An await is the location in the code where the code needs the results from the asynchronous method to move on because downstream code needs the results. Well, the main thread has noting to do when it gets to the last await and it returns to the thread pool (Core) for other processes to use. Once the asynchronous method finishes then another thread takes over to run any remaining code.

    The asynchronous method must be making a call that is not CPU bound. For example, making an HTTP request.

    Please read the official documentation which explains each step of an asynchronous method call more thoroughly than I can in a forum post.

    1 person found this answer helpful.

  3. Bruce (SqlWork.com) 65,316 Reputation points
    2022-09-01T20:02:30.63+00:00

    the code

    await(() => {...})
    someCode()

    is the same as (await is just compiler sugar)

    var task = Task.Run(...);
    var task2 = task.ContinueWith<int>((task) => someCode());

    because you can:

    var task = Task.Run<int>(...);
    var task2 = task.ContinueWith<int>((task) => someCode());
    // do some work
    var someValue = task.Result; // sync wait on task
    // do some work
    var someValue2 = task2.Result; // sync wait on task 2

    the ContinueWith returns a new thread

    note: await and Tasks use a Thread pool. this is different than windows o/s async callbacks where the callback is on the same thread. mutexs are used to only allow one callback at a time.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.