考虑以下两种构造计算1 + 2的Async计算的方法
let c1 =
async {
let a = 1
let b = 2
return a + b }
let c2 =
async {
let a = 1
let! b = async { return 2 }
return a + b }它们之间的实际区别是什么?在我看来,他们做的事情是一样的。例如,为什么你需要使用let! result = streamReader.ReadToEndAsync ()而不是let result = streamReader.ReadToEnd ()呢?当计算运行时,这不是两行都“阻塞”的情况吗?
发布于 2021-03-02 22:53:51
您使用let! b = async { return 2 }的愚蠢示例确实没有带来任何新的东西。它确实完全等同于let b = 2。
然而,ReadToEnd和ReadToEndAsync的故事就不同了。虽然它们都可以被描述为“阻塞”,但它们的阻塞方式是完全不同的。
ReadToEnd是同步的。当在线程上调用它时,该线程会停止并等待它完成。线程被阻塞。它什么也不做,但也不能用来执行其他任何事情。
ReadToEndAsync使用asynchronous I/O (在Windows上也称为"overlapped I/O“)。这基本上意味着线程在这一点上停止,并调用操作系统,说“嘿,请为我读这个文件,并在读完后唤醒我”。它在较低级别上的实现方式根据操作系统的不同而有所不同,但通常在调用完成时会得到某种回调。
这在高可用性、高并发的系统中很重要,比如HTTP服务器。但是,如果您只是在人工监督下在本地计算机上运行脚本,则只需使用更方便的脚本。
有趣的是,同步版本的ReadToEnd实际上也在幕后使用异步I/O,它只是被包装在一个同步阻塞包装器中,以便在简单的情况下更方便地使用。
https://stackoverflow.com/questions/66438571
复制相似问题