Esempio n. 1
0
        public static TResult InvokeWithContext <TResult>(this Func <TResult> function)
        {
            Contract.Requires <ArgumentNullException>(function != null);

            ExecutionContext       executionContext       = ExecutionContext.Capture();
            SynchronizationContext synchronizationContext = SynchronizationContext.Current;

            TaskCompletionSource <TResult> taskCompletionSource = new TaskCompletionSource <TResult>();

            try
            {
                if (synchronizationContext == null)
                {
                    TResult result = function.InvokeWith(executionContext);
                    taskCompletionSource.SetResult(result);
                }
                else
                {
                    // See: System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Create()
                    synchronizationContext.OperationStarted();
                    // See: System.Threading.Tasks.SynchronizationContextAwaitTaskContinuation.PostAction()
                    synchronizationContext.Post(_ =>
                    {
                        try
                        {
                            TResult result = function.InvokeWith(executionContext);
                            // See: System.Runtime.CompilerServices.AsyncVoidMethodBuilder.NotifySynchronizationContextOfCompletion()
                            synchronizationContext.OperationCompleted();
                            taskCompletionSource.SetResult(result);
                        }
                        catch (Exception exception)
                        {
                            taskCompletionSource.SetException(exception);
                        }
                    }, null);
                }
            }
            catch (Exception exception)
            {
                taskCompletionSource.SetException(exception);
            }

            taskCompletionSource.Task.Wait();
            return(taskCompletionSource.Task.Result);
        }