我已经学习C#和Golang有一段时间了,并试图比较它们支持异步编程的方式。
我对goroutines的了解是,go运行时可以调度goroutines在不同的物理/机器线程上运行。如果一个goroutine被阻塞(例如,同步等待I/O),go运行时可以挂起这个goroutine并释放物理线程来运行其他goroutine。
C#Task
类似于goroutine,因为它也是物理线程之上的抽象。但是,在async
Task
中进行阻塞I/O被认为是一个坏主意,因为 “整个线程将被阻塞,导致死锁”。C#运行时不能做一些类似于goroutines的事情来挂起被阻塞的async
Task
并释放物理线程来运行其他async
Task
吗?
我已经为这个问题挣扎了一段时间,找不到更好的公共材料来解释这个问题。也许我的理解是不正确的。有人能帮帮我吗?
1条答案
按热度按时间yhived7q1#
C# Task类似于goroutine,因为它也是物理线程之上的抽象。
从极高的Angular 看,是的,它们可以是相似的。
然而,在异步任务中阻塞I/O被认为是一个坏主意,因为“整个线程将被阻塞,导致死锁”。
阻塞不一定会导致死锁,但是阻塞会阻塞调用线程,直到任务完成。这才是重点
C#运行时不能做一些类似于goroutines的事情来挂起被阻塞的异步任务并释放物理线程来运行其他异步任务吗?
异步方法可以使用
await
来获得您想要的行为。Blocking专门用于阻塞 * 线程 *。从概念上讲,goroutine有点像让每个方法都是async
,并在任何地方隐式地使用await
。在更一般的C#运行时情况下,执行类似于goroutines的 any 阻塞:由于向后兼容性,C#运行时不能轻易地做到这一点。还有很多遗留代码依赖于“特殊线程”(UI线程,COM STA线程等),其中绿色线程/协同程序方法将更加困难。Go通过创建一个全新的生态系统来避免向后不兼容的问题。