我在下面的程序中打印了哪个线程执行每个被调用的方法,结果非常奇怪。我希望所有异步调用都由线程池线程执行,因为@Jon提到异步调用使用threadpool线程,线程池线程是后台线程。
线程id显示,执行Main方法的同一个线程执行除DisplayResult以外的所有调用的方法,后者不是异步方法。
为什么不是异步方法的DisplayResult的每个调用都由线程池线程执行,当调用时实际的异步方法是由非后台线程执行的,与执行主方法的非后台线程相同?在这个程序中应该有多少后台线程和非后台线程?
public static async Task Main()
{
Console.WriteLine($"Main method: The thread executing this task is {Thread.CurrentThread.Name}, {Thread.CurrentThread.ManagedThreadId}");
if (Thread.CurrentThread.IsBackground)
{
Console.WriteLine($"And it is a background thread.");
}
else
{
Console.WriteLine("And it is a non-background thread");
}
Console.WriteLine();
if (Thread.CurrentThread.IsThreadPoolThread)
{
Console.WriteLine("It is a ThreadPoolThread");
}
else
{
Console.WriteLine("It is a non-ThreadPoolThread");
}
Task task1 = ProcessReadWriteAsync(@"/tmp/temp1Write.txt");
Task task2 = ProcessReadWriteAsync(@"/tmp/temp2Write.txt");
await task1;
await task2;
}
public static async Task ProcessReadWriteAsync(string filePath)
{
Console.WriteLine($"ProcessReadWriteAsync: The thread executing this task is {Thread.CurrentThread.Name}, {Thread.CurrentThread.ManagedThreadId}");
if (Thread.CurrentThread.IsBackground)
{
Console.WriteLine($"And it is a background thread.");
}
else
{
Console.WriteLine("And it is a non-background thread");
}
Console.WriteLine();
if (Thread.CurrentThread.IsThreadPoolThread)
{
Console.WriteLine("It is a ThreadPoolThread");
}
else
{
Console.WriteLine("It is a non-ThreadPoolThread");
}
try
{
await ReadWriteAsync(filePath);
} catch (Exception ex)
{
Console.WriteLine(ex.Message);
} finally
{
Console.WriteLine();
}
}
public static async Task ReadWriteAsync(string path, string text)
{
Console.WriteLine($"ReadWriteAsync 2 parameters: The thread executing this task is {Thread.CurrentThread.Name}, {Thread.CurrentThread.ManagedThreadId}");
if (Thread.CurrentThread.IsBackground)
{
Console.WriteLine($"And it is a background thread.");
}
else
{
Console.WriteLine("And it is a non-background thread");
}
Console.WriteLine();
if (Thread.CurrentThread.IsThreadPoolThread)
{
Console.WriteLine("It is a ThreadPoolThread");
}
else
{
Console.WriteLine("It is a non-ThreadPoolThread");
}
FileStream stream = new FileStream(path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite, 4096, useAsync: true);
byte[] buffer = new byte[0x1000];
int noOfCharactersRead = await stream.ReadAsync(buffer, 0, buffer.Length);
DisplayResult(buffer: buffer);
}
public static async Task ReadWriteAsync(string path)
{
Console.WriteLine($"ReadWriteAsync 1 parameters: The thread executing this task is {Thread.CurrentThread.Name}, {Thread.CurrentThread.ManagedThreadId}");
if (Thread.CurrentThread.IsBackground)
{
Console.WriteLine($"And it is a background thread.");
}
else
{
Console.WriteLine("And it is a non-background thread");
}
Console.WriteLine();
if (Thread.CurrentThread.IsThreadPoolThread)
{
Console.WriteLine("It is a ThreadPoolThread");
}
else
{
Console.WriteLine("It is a non-ThreadPoolThread");
}
await ReadWriteAsync(path, "");
}
private static void DisplayResult(byte[] buffer)
{
Console.WriteLine($"DisplayResult: The thread executing this method is {Thread.CurrentThread.Name}, {Thread.CurrentThread.ManagedThreadId}");
if (Thread.CurrentThread.IsBackground)
{
Console.WriteLine($"And it is a background thread.");
}
else
{
Console.WriteLine("And it is a non-background thread");
}
Console.WriteLine();
if (Thread.CurrentThread.IsThreadPoolThread)
{
Console.WriteLine("It is a ThreadPoolThread");
}
else
{
Console.WriteLine("It is a non-ThreadPoolThread");
}
string DecodedText = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
string[] strings = DecodedText.Split('\n');
for (int index = 0; index < strings.Length;index++)
{
Console.WriteLine(strings[index]);
}
}输出:
Main method: The thread executing this task is , 1
And it is a non-background thread
It is a non-ThreadPoolThread
ProcessReadWriteAsync: The thread executing this task is , 1
And it is a non-background thread
It is a non-ThreadPoolThread
ReadWriteAsync 1 parameters: The thread executing this task is , 1
And it is a non-background thread
It is a non-ThreadPoolThread
ReadWriteAsync 2 parameters: The thread executing this task is , 1
And it is a non-background thread
It is a non-ThreadPoolThread
ProcessReadWriteAsync: The thread executing this task is , 1
And it is a non-background thread
It is a non-ThreadPoolThread
ReadWriteAsync 1 parameters: The thread executing this task is , 1
And it is a non-background thread
It is a non-ThreadPoolThread
ReadWriteAsync 2 parameters: The thread executing this task is , 1
And it is a non-background thread
It is a non-ThreadPoolThread
DisplayResult: The thread executing this method is , 4
And it is a background thread.
It is a ThreadPoolThread
1. msdn.microsoft.com/library/hh191443.aspx 83732
2. msdn.microsoft.com/library/aa578028.aspx 205273
3. msdn.microsoft.com/library/jj155761.aspx 29019
4. msdn.microsoft.com/library/hh290140.aspx 117152
5. msdn.microsoft.com/library/hh524395.aspx 68959
6. msdn.microsoft.com/library/ms404677.aspx 197325
7. msdn.microsoft.com 42972
8. msdn.microsoft.com/library/ff730837.aspx 146159
9. msdn.microsoft.com/library/hh191443.aspx 83732
10. msdn.microsoft.com/library/aa578028.aspx 205273
11. msdn.microsoft.com/library/jj155761.aspx 29019
12. msdn.microsoft.com/library/hh290140.aspx 117152
13. msdn.microsoft.com/library/hh524395.aspx 68959
14. msdn.microsoft.com/library/ms404677.aspx 197325
15. msdn.microsoft.com 42972
16. msdn.microsoft.com/library/ff730837.aspx 146159
17. msdn.microsoft.com/library/hh191443.aspx 83732
18. msdn.microsoft.com/library/aa578028.aspx 205273
19. msdn.microsoft.com/library/jj155761.aspx 29019
20. msdn.microsoft.com/library/hh290140.aspx 117152
21. msdn.microsoft.com/library/hh524395.aspx 68959
22. msdn.microsoft.com/library/ms404677.aspx 197325
23. msdn.microsoft.com 42972
24. msdn.microsoft.com/library/ff730837.aspx 146159
25. msdn.microsoft.com/library/hh191443.aspx 83732
26. msdn.microsoft.com/library/aa578028.aspx 205273
27. msdn.microsoft.com/library/jj155761.aspx 29019
28. msdn.microsoft.com/library/hh290140.aspx 117152
29. msdn.microsoft.com/library/hh524395.aspx 68959
30. msdn.microsoft.com/library/ms404677.aspx 197325
31. msdn.microsoft.com 42972
32. msdn.microsoft.com/library/ff730837.aspx 146159
33. msdn.microsoft.com/library/hh191443.aspx 83732
34. msdn.microsoft.com/library/aa578028.aspx 205273
35. msdn.microsoft.com/library/jj155761.aspx 29019
36. msdn.microsoft.com/library/hh290140.aspx 117152
37. msdn.microsoft.com/library/hh524395.aspx 68959
38. msdn.microsoft.com/library/ms404677.aspx 197325
39. msdn.microsoft.com 42972
40. msdn.microsoft.com/library/ff730837.aspx 146159
41. msdn.microsoft.com/library/hh191443.aspx 83732
42. msdn.microsoft.com/library/aa578028.aspx 205273
43. msdn.microsoft.com/library/jj155761.aspx 29019
44. msdn.microsoft.com/library/hh290140.aspx 117152
45. msdn.microsoft.com/library/hh524395.aspx 68959
46. msdn.microsoft.com/library/ms404677.aspx 197325
47. msdn.microsoft.com 42972
48. msdn.microsoft.com/library/ff730837.aspx 146159
49. msdn.microsoft.com/library/hh191443.aspx 83732
50. msdn.microsoft.com/library/aa578028.aspx 205273
51. msdn.microsoft.com/library/jj155761.aspx 29019
52. msdn.microsoft.com/library/hh290140.aspx 117152
53. msdn.microsoft.com/library/hh524395.aspx 68959
54. msdn.microsoft.com/library/ms404677.aspx 197325
55. msdn.microsoft.com 42972
56. msdn.microsoft.com/library/ff730837.aspx 146159
57. msdn.microsoft.com/library/hh191443.aspx 83732
58. msdn.microsoft.com/library/aa578028.aspx 205273
59. msdn.microsoft.com/library/jj155761.aspx 29019
60. msdn.microsoft.com/library/hh290140.aspx 117152
61. msdn.microsoft.com/library/hh524395.aspx 68959
62. msdn.microsoft.com/library/ms404677.aspx 197325
63. msdn.microsoft.c
DisplayResult: The thread executing this method is , 5
And it is a background thread.
It is a ThreadPoolThread
1. msdn.microsoft.com/library/hh191443.aspx 83732
2. msdn.microsoft.com/library/aa578028.aspx 205273
3. msdn.microsoft.com/library/jj155761.aspx 29019
4. msdn.microsoft.com/library/hh290140.aspx 117152
5. msdn.microsoft.com/library/hh524395.aspx 68959
6. msdn.microsoft.com/library/ms404677.aspx 197325
7. msdn.microsoft.com 42972
8. msdn.microsoft.com/library/ff730837.aspx 146159
9. msdn.microsoft.com/library/hh191443.aspx 83732
10. msdn.microsoft.com/library/aa578028.aspx 205273
11. msdn.microsoft.com/library/jj155761.aspx 29019
12. msdn.microsoft.com/library/hh290140.aspx 117152
13. msdn.microsoft.com/library/hh524395.aspx 68959
14. msdn.microsoft.com/library/ms404677.aspx 197325
15. msdn.microsoft.com 42972
16. msdn.microsoft.com/library/ff730837.aspx 146159
17. msdn.microsoft.com/library/hh191443.aspx 83732
18. msdn.microsoft.com/library/aa578028.aspx 205273
19. msdn.microsoft.com/library/jj155761.aspx 29019
20. msdn.microsoft.com/library/hh290140.aspx 117152
21. msdn.microsoft.com/library/hh524395.aspx 68959
22. msdn.microsoft.com/library/ms404677.aspx 197325
23. msdn.microsoft.com 42972
24. msdn.microsoft.com/library/ff730837.aspx 146159
25. msdn.microsoft.com/library/hh191443.aspx 83732
26. msdn.microsoft.com/library/aa578028.aspx 205273
27. msdn.microsoft.com/library/jj155761.aspx 29019
28. msdn.microsoft.com/library/hh290140.aspx 117152
29. msdn.microsoft.com/library/hh524395.aspx 68959
30. msdn.microsoft.com/library/ms404677.aspx 197325
31. msdn.microsoft.com 42972
32. msdn.microsoft.com/library/ff730837.aspx 146159
33. msdn.microsoft.com/library/hh191443.aspx 83732
34. msdn.microsoft.com/library/aa578028.aspx 205273
35. msdn.microsoft.com/library/jj155761.aspx 29019
36. msdn.microsoft.com/library/hh290140.aspx 117152
37. msdn.microsoft.com/library/hh524395.aspx 68959
38. msdn.microsoft.com/library/ms404677.aspx 197325
39. msdn.microsoft.com 42972
40. msdn.microsoft.com/library/ff730837.aspx 146159
41. msdn.microsoft.com/library/hh191443.aspx 83732
42. msdn.microsoft.com/library/aa578028.aspx 205273
43. msdn.microsoft.com/library/jj155761.aspx 29019
44. msdn.microsoft.com/library/hh290140.aspx 117152
45. msdn.microsoft.com/library/hh524395.aspx 68959
46. msdn.microsoft.com/library/ms404677.aspx 197325
47. msdn.microsoft.com 42972
48. msdn.microsoft.com/library/ff730837.aspx 146159
49. msdn.microsoft.com/library/hh191443.aspx 83732
50. msdn.microsoft.com/library/aa578028.aspx 205273
51. msdn.microsoft.com/library/jj155761.aspx 29019
52. msdn.microsoft.com/library/hh290140.aspx 117152
53. msdn.microsoft.com/library/hh524395.aspx 68959
54. msdn.microsoft.com/library/ms404677.aspx 197325
55. msdn.microsoft.com 42972
56. msdn.microsoft.com/library/ff730837.aspx 146159
57. msdn.microsoft.com/library/hh191443.aspx 83732
58. msdn.microsoft.com/library/aa578028.aspx 205273
59. msdn.microsoft.com/library/jj155761.aspx 29019
60. msdn.microsoft.com/library/hh290140.aspx 117152
61. msdn.microsoft.com/library/hh524395.aspx 68959
62. msdn.microsoft.com/library/ms404677.aspx 197325
63. msdn.microsoft.c发布于 2020-04-15 17:39:46
所有异步方法都开始在当前线程上运行。在碰到一个对不完整的await起作用的Task之前,没有什么不同的事情发生。但是,无论您向await提供什么信息,都必须在await实际执行任何操作之前返回一个值(一个Task)。
所以让我们来看看到底发生了什么:
Main一直运行到它调用ProcessReadWriteAsync(@"/tmp/temp1Write.txt")ProcessReadWriteAsync(string)运行,直到它调用ReadWriteAsync(filePath)ReadWriteAsync(string)运行,直到它调用ReadWriteAsync(path, "")ReadWriteAsync(string,string)运行,直到它调用stream.ReadAsync(buffer, 0, buffer.Length)stream.ReadAsync()为止,直到它在ReadWriteAsync(string,string)中返回一个不完整的Taskawait为止,在ReadWriteAsync(string,string)中看到不完整的Task并返回一个新的不完全Task,当该方法的其余部分注册为该TaskReadWriteAsync(string)的延续时,一个不完整的TaskProcessReadWriteAsync(string)返回一个不完整的TaskMain()中还没有await,所以执行继续there.Main()调用ProcessReadWriteAsync(@"/tmp/temp2Write.txt"),这将再次启动整个进程。所有这些都发生在同一个线程上。
当您最后调用await task1时,它告诉它暂停执行,直到Task完成为止。此时,您的代码不再运行。
当stream.ReadAsync()最终完成时,它的Task被设置为Completed,而ReadWriteAsync(string,string)的其余部分一直运行到完成,然后触发ReadWriteAsync(string)运行到完成,然后触发ProcessReadWriteAsync(string)运行到完成。所有这些都发生在后台线程上,这就是为什么您看到DisplayResult在后台线程上运行的原因。
一旦task1设置为完成,您的Main()方法将恢复。
请记住,在具有同步上下文的应用程序(如UI应用程序或ASP.NET (非核心))中,连续性不会发生在后台线程上。它们将发生在与所启动的线程相同的线程上。因此,在这些情况下,延续甚至不会开始,直到您点击await task1。但是,您可以告诉它,您不需要它们返回到与.ConfigureAwait(false)相同的同步上下文。
https://stackoverflow.com/questions/61232914
复制相似问题