await
的作用是在异步操作时释放当前线程,好处是提高线程的利用率
请问老大,await释放的线程是新开的线程吗?因为await不会阻塞主线程,但是这个新开的线程还是要去执行这个异步操作,不明白这一点
@QT2019: 似乎有些异步也是借助于线程池,相当于你把任务放进线程池中让它独自运行了,不会影响主线程的进行,进而提高了代码执行速度
@QT2019: 是把线程放回线程池,执行异步 IO 操作不需要线程,相关博文:一码阻塞,万码等待:ASP.NET Core 同步方法调用异步方法“死锁”的真相
1.异步操作 可以 是开线程执行 实现
2.线程 可以 是从线程池分配,如果线程(该线程由使用的线程池提供)通常数量大于线程池的可用的线程数量,就需要排队
第二条你完全可以自己写个线程池,代码原则上也用不了几行。
线程过多并不一定能提升性能,反而可能降低性能,因为开线程也是需要开销,切换线程也需要开销,线程数量得当,配合不同cpu性能可以更好发挥。不然干嘛比如iis之类的让你设置cpu数量~
带有Async后缀的方法通常是返回一个TASK对象。在一定程度上可以认为是使了新线程。在这里看起来像是有两个线程在工作。
如果你使用了await关键字,那么原来的线程将回到线程池。Async方法后面的代码将会等到Task完成之后并由Task的线程去执行。所以实际相当于只有一个线程在工作。
但如果你用的不是await关键字,而用的是Task.Wait(),那么该线程会一直等待,直到Task结束之后才继续执后面的代码,这就会出现你提到的情况了。
如果创建了 n 个 Task,然后分别安排在线程池中执行,并在每个 Task 中等待任务执行完毕
随后这 n 个 Task 分别再创建了 n 个子 Task,并继续安排在线程池中执行;
这时问题来了,由于前面 n 个 Task 在等待中,所以占用了线程池的线程资源:
如果 n < 线程池最小线程数,那么当前线程池中还有剩余工作线程帮助完成子 Task;
但如果 n >= 线程池最小线程数,那么当前线程池中便没有新的工作线程来完成子 Task;于是一开始的等待也不会完成;必须等线程池开启新的工作线程后,任务才可以继续。
https://blog.walterlv.com/post/task-wait-may-cause-long-time-waiting.html