开发者

Async: Why AsyncDownloadString?

开发者 https://www.devze.com 2023-03-17 22:26 出处:网络
Alright... I\'m getting a bit confused here. The async monad allows you to use let! which will start the computation of the given async method, and suspend the thread, untill the result is available..

Alright... I'm getting a bit confused here. The async monad allows you to use let! which will start the computation of the given async method, and suspend the thread, untill the result is available.. thats all fine, I do understand that.

Now what I dont understand is why they made an extension for the WebClient class, thats named AsyncDownloadString - C开发者_StackOverflowouldn't you just wrap the normal DownloadString inside an async block? I'm pretty sure, I'm missing an important point here, since I've done some testing that shows DownloadString wrapped inside an async block, still blocks the thread.


There is an important difference between the two:

  • The DownloadString method is synchronous - the thread that calls the method will be blocked until the whole string is downloaded (i.e. until the entire content is transferred over the internet).

  • On the other hand, AsyncDownloadString doesn't block the thread for a long time. It asks the operating system to start the download and then releases the thread. When the operating system receives some data, it picks a thread from the thread pool, the thread stores the data to some buffer and is again released. When all data is downloaded, the method will read all data from the buffer and resume the rest of the asynchronous workflow.

In the first case, the thread is blocked during the entire download. In the second case, threads are only busy for very short period of time (when processing received responses, but not when waiting for the server).

Internally, the AsyncDownloadString method is just a wrapper for DownloadStringAsync, so you can also find more information in the MSDN documentation.


The important point to note is that async programming is about doing operations that are not CPU bound i.e those which are IO bound. These IO bound operations are performed on IO threads (using overlapped IO feature of operating system). What this implies is that even if you wrap some factorial function inside a async block and run it inside another async block using let! binding, you won't get any benefit out of it as it will be running on CPU bound thread and the main purpose of doing async programming is to not take up a CPU bound thread when something which is of IO nature, as that CPU bound thread can be used for other purpose in the meantime the IO completes.

If you look at the various IO classes in .NET like File, Socket etc. They all have blocking as well as non blocking read and write operations. The blocking operations will wait for the IO to complete on the CPU thread and hence blocking the CPU thread till IO is done, where as the non blocking operations uses the overlapped IO API calls to perform the operation.

Async have a method to make a async block out of these non blocking APIs of Files, Socket etc. In your case calling DownloadString will block the CPU thread as it uses the blocking API of the underlying class where as AsyncDownloadString uses the non blocking - io overlapped - based API call.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号