You only need to return an awaitable. Task/Task<TResult> is a common choice; Tasks can be created using Task.Run (to execute code on a background thread) or TaskCompletionSource<T> (to wrap an asynchronous event).
Read the Task-Based Asynchronous Pattern for more information.