Example #1
0
        public static void Handle(Func <Task> func)
        {
            using var asyncTaskScheduler = new AsyncTaskScheduler();
            var asyncTaskFactory = new TaskFactory(CancellationToken.None, TaskCreationOptions.HideScheduler, TaskContinuationOptions.HideScheduler, asyncTaskScheduler);

            var asyncSynchronizationContext = new AsyncSynchronizationContext(asyncTaskScheduler,
                                                                              (SendOrPostCallback callback, object state) =>
            {
                var actionTask = asyncTaskFactory.StartNew(() => callback(state), asyncTaskFactory.CancellationToken, TaskCreationOptions.HideScheduler | TaskCreationOptions.DenyChildAttach, asyncTaskScheduler);
                return(actionTask);
            });
            {
                SynchronizationContext oldContext = SynchronizationContext.Current;
                SynchronizationContext.SetSynchronizationContext(asyncSynchronizationContext);

                asyncTaskScheduler.Increment();
#pragma warning disable AsyncFixer04
                var funcTask = asyncTaskFactory.StartNew(func, asyncTaskFactory.CancellationToken,
                                                         TaskCreationOptions.HideScheduler | TaskCreationOptions.DenyChildAttach,
                                                         asyncTaskScheduler).Unwrap();

                var continuationTask = funcTask.ContinueWith(t =>
                {
                    asyncTaskScheduler.Decrement();
                    t.GetAwaiter().GetResult();
                }, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, asyncTaskScheduler);
#pragma warning restore AsyncFixer04

                var tasks = asyncTaskScheduler.GetConsumingEnumerable();
                foreach (var(hasAwait, t) in tasks)
                {
                    asyncTaskScheduler.PublicTryExecuteTask(t);
                    if (hasAwait)
                    {
                        t.GetAwaiter().GetResult();
                    }
                }
                // wait till continuationTask end - means we can use asyncTaskScheduler in the using block
                continuationTask.GetAwaiter().GetResult();

                SynchronizationContext.SetSynchronizationContext(oldContext);
            }
        }
Example #2
0
 public bool IsInlineTo(AsyncTaskScheduler asyncTaskScheduler)
 {
     return(this.asyncTaskScheduler == asyncTaskScheduler);
 }
Example #3
0
 public AsyncSynchronizationContext(AsyncTaskScheduler asyncTaskScheduler, Func <SendOrPostCallback, object, Task> startNew)
 {
     this.asyncTaskScheduler = asyncTaskScheduler;
     this.startNew           = startNew;
 }