Reputation: 467
I read the article on copying streams asynchronously. I noticed that only one buffer is being used to read/write.
Where does doing a stream copy using the asynchronous calls gain me something?
Because of one buffer it seems that your asynchronous solution at runtime is very synchronous. The write has to wait for the read and the next read had to wait until the buffer is written.
Some thoughts:
I have seen variants using multiple buffers. IMHO that only makes stuff more complex, uses more memory and postpones the problem. It allows multiple reads in parallel to writing to some extend.
In case of files I can imagine a more relaxed solution for writing: writing a block when read and fixing the order when all files are read. (file system must support this).
I read the article because I am using .NET 3.5 and cannot use .NET 4 or 4.5 yet.
(The netqa at Microsoft dot com adres bounces)
Upvotes: 0
Views: 358
Reputation: 244787
The write has to wait for the read
Of course it does. What would you write if you didn't read the data yet?
the next read had to wait until the buffer is written.
Avoiding this might make sense in some cases, but you would really need to profile that. Various caches and the way data is read and written from a hard disk could affect this. If there was some performance benefit, it probably wouldn't be very big.
Now to your main question:
Where does doing a stream copy using the asynchronous calls gain me something?
The gain comes from the fact that you're not blocking any thread, while the IO takes place. This is important for performance, because threads are expensive resources (among other things, each requires 1 MB of both virtual and physical memory). This can make huge difference in an environment like ASP.NET, where each request is processed by different thread.
If you're writing a desktop application that just copies a few files, this probably won't matter to you, as long as you don't block the UI thread.
Upvotes: 1
Reputation: 60190
Async processing helps whenever you're dealing with non-CPU-related latencies and want to avoid those without spanning insane amounts of threads (which doesn't scale well - there shouldn't be too many threads per CPU because threads are "expensive" resources, abundant context switching can kill your performance).
Typical benefactors are therefore IO operations, since both disk and network are "slow" compared to the computing effort required for processing the data. So whenever you may have many parallel streams (network and disk) you should use async operations to deal with them.
That said, proper async programming is hard, especially without the baked-in support in the new .NET compilers.
A good async copy should use at least two buffers; one reads data (async) and one writes data (async) concurrently. Of course the idle writer will only start after the reader is done with its block, and the idle reader will only start when there is at least a spare buffer (e.g. writer has finished writing). When you have one buffer only, there will be breaks between consecutive read and write operations, e.g. it will always be "read, write, read, ...write" instead of "read, read+write, read+write, ...write".
Upvotes: 2