Home > Blockchain >  Switching between threads with async/await in C#
Switching between threads with async/await in C#

Time:06-17

In the code below Main() is resumed on a separate thread after HTTP response is received:

static async Task Main(string[] args)
{
    try
    {
        HttpClient client = new HttpClient();

        Console.WriteLine($"Thread: {Thread.CurrentThread.ManagedThreadId}");
             
        HttpResponseMessage response = await client.GetAsync("https://developernote.com/");

        Console.WriteLine($"Thread: {Thread.CurrentThread.ManagedThreadId}");
    }
    catch (HttpRequestException e)
    {
        Console.WriteLine("\nException Caught!");
        Console.WriteLine("Message :{0} ", e.Message);
    }
}

The output is:

Thread: 1
Thread: 7
  1. How do I switch back to the main thread? So the code would be something like this:

    await switchToMainThread();

  2. Can someone give me an example of how to create a Task that switches to a different thread using ThreadPool?

  3. Why the exception is caught on a separate thread?

CodePudding user response:

Not sure if this is what you are looking for but one way I can think of is to execute the async code separately and (optionally) wait for it:

Console.WriteLine($"Thread: {Thread.CurrentThread.ManagedThreadId}");

var task = Task.Run(async () =>
{
    using var http = new HttpClient();
    await http.GetAsync("https://www.example.com");
    Console.WriteLine($"Requests done in Thread: {Thread.CurrentThread.ManagedThreadId}");
});

Console.WriteLine($"Other things in Thread: {Thread.CurrentThread.ManagedThreadId}");

task.Wait();

Console.WriteLine($"Other things after http finished in Thread: {Thread.CurrentThread.ManagedThreadId}");

Output:

Thread: 1
Other things in Thread: 1
Requests done in Thread: 10
Other things after http finished in Thread: 1

CodePudding user response:

If you want to continue on the thread on which you invoked the async method, you are actually following a synchronous execution model here. (A thread cannot execute two threads at once; it cannot return from the async (main) method and execute whatever else code is to be executed while at the same time also executing the continuation of the client.GetAsync() task.)

As such, you could perhaps call client.GetAsync() in a (synchronous) blocking manner without using the state machine behind await that's responsible for the synchronization context / thread switching:

HttpResponseMessage response = client.GetAsync("https://developernote.com/")
    .GetAwaiter()
    .GetResult();
  • Related