I agree with Marx and Stephen (Cleary).
(BTW, I started writing this as a comment on Stephen, but it turned out to be too long, let me know whether it is normal to write it as an answer or not, and feel free to take a bit from and add it to Stephen's answer, in the spirit of “providing the best answer” )
It really "depends": as Mark said, it is important to know how DoSomethingAsync is asynchronous. We all agree that it makes no sense to use the "sync" method to call the "async" and "wait" methods: this can be done in the user code. The only advantage of using a separate method is to have an actual performance gain, to have an implementation that is different under the hood and adapted to a synchronous scenario. This is especially true if the async method creates a thread (or receives it from a threadpool): you get something that uses two “control flows” underneath, while a “promising” one with its synchronous look should execute in the caller’s contexts. It may even have concurrency problems, depending on the implementation.
Also in other cases, such as the intense I / O that the OP mentions, it might be worth having two different implementations. Most operating systems (of course, Windows) have different I / O mechanisms adapted to two scenarios: for example, performing async and I / O operations have great advantages over OS-level mechanisms such as I / O completion ports, which add a bit of overhead expenses (not significant, but not zero) in the core (in the end, they should do accounting, shipping, etc.) and a more direct implementation for synchronous operations. The complexity of the code also varies greatly, especially in those functions where several operations are performed / coordinated.
What would I do:
- have some examples / tests for typical use and scenarios
- see which version of the API is used, where and measure. Also measure the performance difference between the pure sync and sync options. (not for the whole API, but for a few typical cases).
- Based on the measurement, decide if the extra cost is worth it.
This is mainly because the two goals somehow contrast with each other. If you need supported code, the obvious choice is synchronization from the point of view of async / wait (or vice versa) (or, even better, provide only an asynchronous option and allow the user to "wait"); if you need performance, you must implement two functions in different ways, use different basic mechanisms (from the framework or from the OS). I think this should not change in terms of unit testing, how you actually implement your API.
Lorenzo Dematté Feb 21 '13 at 10:42
source share