I am quite new to Metro dev and I only hope I will be able to express my question in an understandable way...
Actually I am porting a part of my old application to Metro. The logic part is a separated project (Portable Library) and it should serve to 1) the old WPF app and 2) the new Metro app. The basic logic is the same but some subsystems (for example file operations manager) must be coded differently - i.e. async way for Metro.
My question is: Do I have to rewrite the whole chain of methods caller-callee to the new async paradigm? Let's say I have a chain of 4 methods, starting by method A = Metro UI event async handler (it makes sense to me to code it as async void as it is the top fire&forget event), through the next 2 methods (B and C) placed in different layers of my application, down to the method D containing "await CreateFileAsync" method (made async by Microsoft).
Now: async CreateFileAsync method should be called with await. That forces me to make method D async too. To call method D from C and C from B and B from A - do I have to rewrite all A, B and C into the async-await style?
I can feel I am missing a deeper knowledge so I am trying to educate myself but concurrently I wanted to try my luck here...
Do I have to rewrite a big part of my code? Is any of my statements above wrong?
Many thanks in advance, Hans
I recommend that you do rewrite your portable library to be asynchronous. It's not as bad as it used to be; Microsoft worked very hard on
async
/await
to make it as easy as possible to convert synchronous code to asynchronous. I expect that a whole lot of others will be doing the same in the near future, and R# will probably implement a "make async" rewriting.There are non-obvious pitfalls when mixing synchronous and asynchronous code - see Stephen Toub's last blog post Should I expose synchronous wrappers for asynchronous methods? For this reason, I think it's just cleaner to expose asynchronous operations as asynchronous APIs (and synchronous operations as synchronous APIs).
Update: If you do want synchronous code to call asynchronous code, then you can use the
Task.WaitAndUnwrapException
extension method in my AsyncEx library. However, you still have the problems mentioned in Stephen Toub's post, namely these:ConfigureAwait(false)
everywhere it can.(2) is not that common anymore, but (1) is a real possibility. It's regularly brought up by people who are just testing out
async
so they mix it with synchronous code.