Stephen Toub covers all the various approaches with their corresponding drawbacks on his blog.
There are only two general-purpose solutions, neither of which is ideal:
- Duplicate the logic in your layer; have your synchronous methods call the synchronous methods in the library. (This assumes that the library has synchronous methods as well as asynchronous).
- Block on the returned task, similar to your example code. This assumes that the library always uses
ConfigureAwait(false)
, an assumption that is out of your control. If the library is context-free, then it may be safer to throw the asynchronous invocation into aTask.Run
and block on that task instead. Also, ensure you unwrap exceptions when blocking on a task, sinceWait
orResult
will wrap exceptions in anAggregateException
.
Both of these solutions have somewhat serious maintenance problems.