在第一个程序中,如您所见,初学者线程
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
*/
这是由所使用的
SynchronziationContext
管理的。使用 await SomethingAsync().ConfigureAwait(true);
可能会帮助您在正确的线程上运行。