关于长时任务中ConfigureAwait(false)与LongRunning线程的作用疑问
首先明确几个核心点,直接纠正你的误解:
LongRunning线程的生命周期只到第一个await之前
你用Task.Factory.StartNew(async () => { ... }, TaskCreationOptions.LongRunning)创建的专用线程,只会执行到第一个await之前的同步代码——也就是进入while循环、调用Task.Delay的瞬间,这个专用线程就会结束(因为async方法遇到await会挂起,当前线程不再持有执行权)。后续所有的循环逻辑,包括await完成后的代码,都和这个LongRunning线程无关了。ConfigureAwait(false)不是后续代码跑在ThreadPool的原因
不管你加不加ConfigureAwait(false),在没有同步上下文(比如后台服务、控制台程序)的环境下,await完成后的代码都会由ThreadPool线程调度执行。ConfigureAwait(false)的作用只是避免捕获原来的同步上下文(如果有的话),不会主动切换到ThreadPool——本质是让代码在任意可用线程(通常就是ThreadPool)上继续,而不是必须回到原来的线程。你的代码等同于在ThreadPool启动任务,还多浪费了一个线程
因为LongRunning线程只执行了几行同步代码就结束了,后续所有循环逻辑都在ThreadPool上跑,和直接用Task.Run启动任务的效果完全一致,但平白多创建了一个一次性的专用线程,反而浪费系统资源。
另外补充一个代码问题:Task.Factory.StartNew传入async lambda时,返回的是Task<Task>(外层任务表示lambda的启动完成,内层任务才是lambda里异步逻辑的完成),你应该改用Task.Run(它会自动处理async lambda,返回正确的Task),或者给StartNew的结果调用.Unwrap()来获取真正的异步任务。
内容的提问来源于stack exchange,提问作者Duagt

