I am trying to port some TcpClient dependant code to .net 4.5, using StreamSocket and DataReader instead.
I have a function named ReadLine() which is used everywhere. By using DataReader in the body (LoadAsync()) of this code, my method is forced to be marked with the async keyword.
The chain reaction is as follows:
Now I have hundreds of places where I have to add async to calling methods and apply await to underlying async method calls.
This leads me to my next question…
Is there an easy way to wrap ReadLine() so that calling methods are not aware that it’s an asynchronous method, so that I don’t have to change the rest of my code?
Also…
I often use this method call in a loop, from multiple places. If these methods are now marked async, i’m afraid I might be reading data off a stream when I shouldn’t be, which will cause all sorts of nightmares. Is it a problem or am I thinking too far ahead?
If you always use
awaitwhenver you call*Asyncmethods, then yourasyncmethods will act just like synchronous methods (except they won’t block). So usingawaitin a loop will work just like you expect.asyncdoes indeed “grow” through the code base. I usually think of this as similar to the old story about “turtles all the way down”; others have called it a “zombie virus”.I describe the deadlock situation in detail on my blog. As I state there, the best option is to allow
asyncto grow.If you must create a synchronous wrapper for an asynchronous method, see Stephen Toub’s advice. You can use
Task.Result, but you need to do two things:ConfigureAwait(false)everywhere. This will sidestep the deadlock situation.Resulthas different error handling semantics.For your particular example, something like this should suffice:
Please carefully consider the complexity before choosing a mixed synchronous/asynchronous code base. It’s not as easy as it first appears.
P.S. Generally speaking, TCP/IP code should all be asynchronous anyway. It’s usually a good idea to have a continuous asynchronous read going on a socket.