Stream.BeginRead()將回調函數作爲參數之一。該回調函數應該被異步調用,但.net通過直接調用BeginRead()中的回調函數來僞造。爲什麼會發生? Read()和BeginRead()之間似乎沒有區別。
請參考下面的堆棧視圖:爲什麼Stream.BeginRead()是同步的?
回答
由於the documentation for Stream
表示:
的BeginRead的溪流上的默認實現調用Read方法同步,這意味着讀可能會阻止在一些溪流上。但是,如果實例已經異步打開,FileStream和NetworkStream等類的實例完全支持異步操作。因此,對BeginRead的調用不會阻塞這些流。 您可以覆蓋BeginRead(例如,通過使用異步委託)以提供異步行爲。
換句話說,它是由每個Stream
子類提供真正的異步行爲。
現在,你在堆棧跟蹤看到ConnectStream
的情況下,這是另一個.NET類(內部,無證),它實際上並提供異步執行的BeginRead()
。這可以在the source code中看到。但是,異步操作通常還有另一個重要規則:異步操作the APM可能實際上完全同步完成。甚至有a property on IAsyncResult來表明這種情況。
事實上,事實證明許多異步API都是這種情況。例如,當使用await
時,可能該方法將而不是返回到await
表達式,而是將立即檢索完成結果並繼續在當前線程中執行。這種情況不僅發生在awaitable只是一個裝在異步包裝中的同步操作時,而且通常是一個異步操作實際上可以同步完成時。
我敢肯定,如果你要檢查你的回調IAsyncResult.CompletedSynchronously
財產,你會發現它被設置爲true
,因爲它應該在API同步完成異步操作是。該屬性主要存在於這種場景中,以防您自己的代碼需要區分異步完成的操作和同步完成的操作(通常,它不應該,但我們都知道代碼並非總是應該如此,甚至有時不能:))。
以下部分根本不對:如果FileStream和NetworkStream等類的實例完全支持異步操作(如果實例已異步打開)。我知道這些文件是這麼說的,但事實並非如此。我想這只是衆多.net craps中的一個。 – moose
@moose:請舉。因爲這兩個類都有很多使用異步操作的異步代碼示例。當然,FileStream需要使用FileOptions.Asynchronous。在那裏,如果你沒有正確初始化對象,你將不會得到你想要的行爲。但是'NetworkStream.BeginRead()'_always_直接到'Socket.BeginReceive()',它本身是絕對異步的。 –
我不知道該說些什麼,但是我親眼看到了堆棧。它顯示的是同步的。根據文檔所述,我會說你可以使用BeginRead(),並且一些內部邏輯將決定它是異步還是同步。根本沒有用(對我來說)。 – moose
- 1. Stop Stream.BeginRead()
- 2. 什麼是同步 - 屬性?
- 3. 什麼是「同步點」?
- 4. 同步是什麼意思?
- 5. 爲什麼不同步?
- 6. 爲什麼不同步而不是異步?
- 7. Couchbase lite android - 什麼是同步的,什麼不是?
- 8. 這種同步的重點是什麼?
- 9. 同步(類參考)是做什麼的?
- 10. 什麼是golang中的同步(sync.RWMutex)
- 11. 什麼是asp.net中的同步?
- 12. 什麼是Dalvik VM的同步代碼?
- 13. 什麼是java中的線程同步?
- 14. 爲什麼我的線程不同步?
- 15. 爲什麼同步安全的整數?
- 16. 爲什麼HandlerThread的run()方法的一部分是同步的?
- 17. 爲什麼write(..)方法的java.io.Writer是同步的?
- 18. 爲什麼DbConnection.OpenAsync(CancellationToken)的默認實現是同步的?
- 19. 什麼是靜態方法同步嗎?
- 20. 什麼是同步語句用於?
- 21. 爲什麼要同步一個同步列表?
- 22. 哈希表:爲什麼get方法是同步的?
- 23. 爲什麼StringBuilder訪問似乎是同步的?
- 24. QTimer爲什麼不是異步的?
- 25. 爲什麼javascript回調是異步的?
- 26. 爲什麼在裏面等待同步?
- 27. 爲什麼Outlook沒有同步
- 28. 爲什麼不在Monotouch中同步TaskScheduler.FromCurrentSynchronizationContext?
- 29. 爲什麼我需要同步由Collections.synchronizedList
- 30. 爲什麼代碼遵循同步?
假設有數據立即可用,爲什麼*不會*你想讓它同步回叫你? –
fwiw,文檔(https://msdn.microsoft.com/en-us/library/system.io.stream.beginread(v=vs.110).aspx)在基礎'Stream.BeginRead ()'實現。 –
IIRC默認流實現將所有異步調用傳遞到同步方法。這是由子類的實現者提供的異步方法實現。它們並不是默認的。您正在使用的Stream實現可能沒有APM方法的實現。基於任務的方法默認使用APM方法。 – spender