Exemple #1
0
        /// <summary>
        /// Synchronously executes a cancelable async task with a void return value.
        /// If the current thread is being aborted or interrupted then a corresponding cancellation request is issued for the given task.
        /// </summary>
        /// <param name="task">The cancelable async task to execute.</param>
        public static void Execute(Func <CancellationToken, Task> task)
        {
            if (task == null)
            {
                throw new ArgumentNullException(nameof(task));
            }

            try
            {
                var savedContext = SynchronizationContext.Current;
                using (var cts = new CancellationTokenSource())
                {
                    Task pendingTask = null;
                    var  context     = new ExclusiveSynchronizationContext();
                    try
                    {
                        SynchronizationContext.SetSynchronizationContext(context);
                        context.Execute(() => pendingTask = task(cts.Token));
                        pendingTask = null;
                    }
                    catch (Exception ex) when(ex is ThreadAbortException || ex is ThreadInterruptedException)
                    {
                        cts.Cancel();

                        if (pendingTask != null)
                        {
                            context.ExceptionFilter = exception => !(exception is TaskCanceledException);

                            // Execute remaining async iterations and finalizers.
                            context.Execute(() => pendingTask);
                        }

                        throw;
                    }
                    finally
                    {
                        SynchronizationContext.SetSynchronizationContext(savedContext);
                    }
                }
            }
            catch (AggregateException e) when(e.InnerExceptions.Count == 1)
            {
                throw e.InnerExceptions[0];
            }
        }
Exemple #2
0
        /// <summary>
        /// Synchronously executes an async task with a void return value.
        /// </summary>
        /// <param name="task">The async task to execute.</param>
        public static void Execute(Func <Task> task)
        {
            if (task == null)
            {
                throw new ArgumentNullException(nameof(task));
            }

            var savedContext = SynchronizationContext.Current;
            var context      = new ExclusiveSynchronizationContext();

            try
            {
                SynchronizationContext.SetSynchronizationContext(context);
                context.Execute(task);
            }
            finally
            {
                SynchronizationContext.SetSynchronizationContext(savedContext);
            }
        }