【发布时间】:2026-01-05 20:55:02
【问题描述】:
我看到很多帖子解释 C# 中的 async/await 不要创建像这样的新线程:tasks are still not threads and async is not parallel。我想自己测试一下,所以我写了这段代码:
private static async Task Run(int id)
{
Console.WriteLine("Start:\t" + id + "\t" + System.Threading.Thread.CurrentThread.ManagedThreadId);
System.Threading.Thread.Sleep(500);
Console.WriteLine("Delay:\t" + id + "\t" + System.Threading.Thread.CurrentThread.ManagedThreadId);
await Task.Delay(100);
Console.WriteLine("Resume:\t" + id + "\t" + System.Threading.Thread.CurrentThread.ManagedThreadId);
System.Threading.Thread.Sleep(500);
Console.WriteLine("Exit:\t" + id + "\t" + System.Threading.Thread.CurrentThread.ManagedThreadId);
}
private static async Task Main(string[] args)
{
Console.WriteLine("Action\tid\tthread");
var task1 = Run(1);
var task2 = Run(2);
await Task.WhenAll(task1, task2);
}
令人惊讶的是,我最终得到了如下所示的输出:
Action id thread
Start: 1 1
Delay: 1 1
Start: 2 1
Resume: 1 4 < ------ problem here
Delay: 2 1
Exit: 1 4
Resume: 2 5
Exit: 2 5
在我看来,确实是在创建新线程,甚至允许两段代码同时运行?我需要在非线程安全的环境中使用 async/await,所以我不能让它创建新线程。为什么任务“2”当前正在运行时允许任务“1”恢复(Task.Delay 之后)?
我尝试将ConfigureAwait(true) 添加到所有await 中,但没有任何改变。
谢谢!
【问题讨论】:
-
您是说您有一段特定的代码需要一次访问一个线程吗?因为同步锁定可以让你做到这一点。
-
我需要这种更通用的方式。我希望能够对将在单个线程上异步运行的任务进行排队,并且当一个任务“等待”时,其他任务可以在该线程上运行
-
从 async/await 中使用不会导致创建新线程,CLR 从线程池线程中使用此目的。
-
谢谢@RahmatAnjirabi!我假设这是等待/没有正确理解。一如既往地感谢支持。虽然不知道为什么我被否决了......
标签: c# multithreading async-await