public static IAsyncResult ToAsyncResult()

in src/Microsoft.Azure.Relay/Common/TaskEx.cs [309:355]


        public static IAsyncResult ToAsyncResult<TResult>(this Task<TResult> task, AsyncCallback callback, object state, bool executeSynchronously = false)
        {
            // Tasks ALWAYS report IAsyncResult.CompletedSynchronously = false.  This can lead to StackOverflow problems
            // when interoping with normal IAsyncResult patterns because if IAsyncResult.CompletedSynchronously == false then
            // it's supposed to be 'safe' to invoke continuations from the AsyncCallback.  This isn't necessarily true
            // with Tasks, so in order to break the stack overflow chain don't pass the TaskContinuationOptions.ExecuteSynchronously
            // flag.  However, this comes with a performance hit.  If we have a task that is not completed, it's safe to use 
            // the ExecuteSynchronously flag since we know the task had to complete asynchronously (as opposed to lying to us).
            var continuationOptions = task.IsCompleted || !executeSynchronously ? TaskContinuationOptions.None : TaskContinuationOptions.ExecuteSynchronously;

            if (task.AsyncState == state)
            {
                if (callback != null)
                {
                    task.ContinueWith(
                        t => callback(task),
                        continuationOptions);
                }

                return task;
            }

            var tcs = new TaskCompletionSource<TResult>(state);
            task.ContinueWith(
                (t, s) =>
                {
                    var tcsPtr = (TaskCompletionSource<TResult>)s;
                    if (t.IsFaulted)
                    {
                        tcsPtr.TrySetException(t.Exception.InnerExceptions);
                    }
                    else if (t.IsCanceled)
                    {
                        tcsPtr.TrySetCanceled();
                    }
                    else
                    {
                        tcsPtr.TrySetResult(t.Result);
                    }

                    callback?.Invoke(tcsPtr.Task);
                },
                tcs,
                continuationOptions);

            return tcs.Task;
        }