为什么 async-await 使用有不同的行为?

问题描述 投票:0回答:1

在第一个程序中,如您所见,初学者线程

1
开始执行。在中间或某处,在打印点时,另一个名为
10
的线程开始发挥作用。当它完成与
FetchAndShowHeaders
方法的关系时,它就消失了。然后,初学者线程
1
继续前进,直到
Main
方法(无需显式编写Main方法)。

在第二个程序中,如您所见,初学者线程

5
开始执行。在等待
FetchAndShowHeaders
的补充时,初学者线程
5
在控制台上写入了 121(11*11) 个点,另一个线程
9
开始在
FetchAndShowHeaders
方法及其延续中获取结果。 重要的部分开始了。与第一个程序不同,在第二个程序中,用于
FetchAndShowHeaders
方法的线程继续执行
Main()
,而不是初学者线程
5

这让我很困惑。可以详细教教我吗?

第一个节目

Console.WriteLine("print1 Thread Name = {0}", Thread.CurrentThread.ManagedThreadId);
Task q = FetchAndShowHeaders("http://www.fultonbank.com");
Console.WriteLine("print2 Thread Name = {0}", Thread.CurrentThread.ManagedThreadId);
for (int i = 0; i < 500_000_0; i++)
{
    for (int ii = 0; ii < 500; ii++)
    {
        if (i % 500_000 == 0)
            Console.Write(".");
    }
}
Console.WriteLine("\nprint5 Thread Name = {0}", Thread.CurrentThread.ManagedThreadId);
await q;
Console.WriteLine("print6 Thread Name = {0}", Thread.CurrentThread.ManagedThreadId);
return;

async Task FetchAndShowHeaders(string url)
{
    using var w = new HttpClient();
    var req = new HttpRequestMessage(HttpMethod.Head, url);
    Console.WriteLine("\nprint3_method_inside Thread Name = {0}", Thread.CurrentThread.ManagedThreadId);
    var response = await w.SendAsync(req, HttpCompletionOption.ResponseHeadersRead);
    Console.WriteLine(System.Text.Json.JsonSerializer.Serialize(
        response.Headers.ToString()));
        Console.WriteLine("\nprint4_method_inside Thread Name = {0}", Thread.CurrentThread.ManagedThreadId);
}

//Output:
/*
print1 Thread Name = 1

print3_method_inside Thread Name = 1
print2 Thread Name = 1
......................................
................................."Date: Sat, 10
 Feb 2024 21:08:01 GMT\r\nConnection: keep-alive\r\nSet-Cookie: 
AWSALB=yoEkz4GX4D6NZxccaPs1OQfQGu0yNRocZplmI6TE1pU1GB2BNwAcQ01\u002Bc; Expires=Sat,
 17 Feb 2024 21:08:01 GMT; Path=/, AWSALBCORS=yoEkz4GX4D6NZIci84X7t\u
 002BNwAcQ01\u002Bc; Expires=Sat, 17 Feb 2024 21:08:01 GMT; Path=/; 
 SameSite=None; Secure, ASP.NET_SessionId=al3ekazz02q0up1oja4i0ify; 
 path=/; HttpOnly; SameSite=Lax,\r\nX-Frame-Options: 
 DENY\r\nStrict-Transport-Security: 
 max-age=31536000;includeSubDomains\r\nX-Content-Type-Options: 
 nosniff\r\nX-XSS-Protection: 1; mode=block\r\n"

print4_method_inside Thread Name = 10
.................................................................
............................................................................
print5 Thread Name = 1
print6 Thread Name = 1
*/

第二个节目

Console.WriteLine("print1 Thread Name = {0}", Thread.CurrentThread.ManagedThreadId);
Task q = FetchAndShowHeaders("http://www.fultonbank.com");
Console.WriteLine("print2 Thread Name = {0}", Thread.CurrentThread.ManagedThreadId);
for (int i = 0; i < 11; i++)
{
    for (int ii = 0; ii < 11; ii++)
    {
        Console.Write(".");
    }
}
Console.WriteLine("\nprint5 Thread Name = {0}", Thread.CurrentThread.ManagedThreadId);
await q;
Console.WriteLine("print6 Thread Name = {0}", Thread.CurrentThread.ManagedThreadId);
return;

async Task FetchAndShowHeaders(string url)
{
    Console.WriteLine("\nprint3_method_inside Thread Name = {0}", Thread.CurrentThread.ManagedThreadId);
        await Task.Delay(1000);
        Console.WriteLine("\nprint4_method_inside Thread Name = {0}", Thread.CurrentThread.ManagedThreadId);
}

//Output:
/*
print1 Thread Name = 5

print3_method_inside Thread Name = 5
print2 Thread Name = 5
.........................................................................................................................
print5 Thread Name = 5

print4_method_inside Thread Name = 9
print6 Thread Name = 9
*/
c# asynchronous async-await
1个回答
0
投票

这是由所使用的

SynchronziationContext
管理的。使用
await SomethingAsync().ConfigureAwait(true);
可能会帮助您在正确的线程上运行。

© www.soinside.com 2019 - 2024. All rights reserved.