首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么Stream.BeginRead()是同步的?

为什么Stream.BeginRead()是同步的?
EN

Stack Overflow用户
提问于 2015-11-03 02:15:41
回答 1查看 738关注 0票数 1

Stream.BeginRead()将回调函数作为参数之一。应该异步调用这个回调函数,但是.net通过直接从BeginRead()调用回调函数来伪造这个函数。为什么会发生这种事?看起来,Read()和BeginRead()之间没有什么区别。

请参见下面的堆栈视图:

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-11-03 05:11:42

正如Stream所指出的:

流上的BeginRead的默认实现同步调用Read方法,这意味着读取可能会阻塞某些流。但是,如果实例是异步打开的,FileStream和NetworkStream等类的实例完全支持异步操作。因此,对BeginRead的调用不会阻塞这些流。您可以重写BeginRead (例如,通过使用异步委托)来提供异步行为

换句话说,要由每个Stream子类来提供真正的异步行为。

现在,在堆栈跟踪中看到的ConnectStream中,这是另一个.NET类(内部的,没有文档的),它实际上提供了BeginRead()的异步实现。这可以在源代码中看到。但是,通常异步操作还有另一个重要规则:异步操作遵循 APM ,实际上可以同步完成。甚至还有IAsyncResult上的一个属性来表示这种情况。

事实上,许多异步API都是这样的。例如,当使用await时,该方法可能不会返回到await表达式,而是会立即检索完成结果,并继续在当前线程中执行。这不仅是当awaitable只是一个在异步包装中修饰的同步操作时发生的,而且还发生在通常是异步操作实际上可以同步完成的时候。

我确信,如果要在回调中检查IAsyncResult.CompletedSynchronously属性,就会发现它被设置为true,就像API同步完成异步操作时一样。该属性主要存在于这种场景中,以防您自己的代码需要区分异步完成的操作和同步完成的操作(一般来说,不应该这样做,但我们都知道代码并不总是应该的,有时甚至不能:)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33490349

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档