I am implementing an interface method that is asynchronous (returns Task). However, my implementation is by necessity synchronous. What's the best way to do this? Is there some built-in way to do this? Here are several options I'm considering:
Option 1: Task.FromResult
return Task.FromResult(ComputeResult());
This is good because my code runs synchronously. The disadvantage is that if ComputeResult() fails or is canceled my method throws instead of returning a failed task.
Option 2: Task.Run
return Task.Run(() => ComputeResult());
This propagates failure and cancellation more naturally. However, this also introduces an unnecessary thread-hop.
Option 3: TaskCompletionSource
var tcs = new TaskCompletionSource<T>(); try { tcs.SetResult(ComputeResult()); } catch (OperationCanceledException) { tcs.SetCanceled(); } catch (Exception ex) { tcs.SetException(ex); } return tcs.Task;
This both propagates failure/cancellation AND avoids the thread-hop, but it's more verbose and complex.