Esempio n. 1
0
    /// <summary>
    /// Runs the function inside a message loop and continues pumping messages
    /// until the returned task completes.
    /// </summary>
    /// <returns>The completed task returned by the delegate's invocation</returns>
    public static Task Run(Func <Task> function)
    {
        using (SynchronizationContextSwitcher.Capture())
        {
            Dispatcher      dispatcher = Dispatcher.CurrentDispatcher;
            DispatcherFrame frame      = new DispatcherFrame(exitWhenRequested: true);

            var message = new TaskFunctionLaunchMessage(function, dispatcher, frame);

            // queue up our first message before we run the loop
            dispatcher.BeginInvoke(new Action(message.LaunchMessageImpl));

            // run the actual WPF message loop
            Dispatcher.PushFrame(frame);

            // PushFrame() has returned. Because we set Contine = false
            // in a continuation of the task, this can only occur if the task
            // has also completed.

            if (message.ReturnedTask != null)
            {
                message.ReturnedTask.RethrowForCompletedTasks();
            }

            return(message.ReturnedTask);
        }
    }
Esempio n. 2
0
        /// <summary>
        /// Wraps a <see cref="Task{TResult}" /> into the Begin method of an APM pattern.
        /// </summary>
        /// <typeparam name="TResult">The type of the result.</typeparam>
        /// <param name="task">The task to wrap. May not be <c>null</c>.</param>
        /// <param name="callback">The callback method passed into the Begin method of the APM pattern.</param>
        /// <param name="state">The state passed into the Begin method of the APM pattern.</param>
        /// <returns>
        /// The asynchronous operation, to be returned by the Begin method of the APM pattern.
        /// </returns>
        public static IAsyncResult ToBegin <TResult>(Task <TResult> task, AsyncCallback callback, object state)
        {
            TaskCompletionSource <TResult> tcs = new TaskCompletionSource <TResult>(state, TaskCreationOptions.RunContinuationsAsynchronously);

            SynchronizationContextSwitcher.NoContext(() => CompleteAsync(task, callback, tcs));
            return(tcs.Task);
        }
Esempio n. 3
0
    public static Task Run(Func <Task> asyncMethod)
    {
        using (SynchronizationContextSwitcher.Capture())
        {
            var customContext = new Context();
            SynchronizationContext.SetSynchronizationContext(customContext);

            var task = asyncMethod.Invoke();

            if (task != null)
            {
                // register a continuation with the task, which will shut down the loop when the task completes.
                task.ContinueWith(_ => customContext.WorkQueue.Shutdown(), TaskContinuationOptions.ExecuteSynchronously);
            }
            else
            {
                // the delegate returned a null Task (VB/C# compilers never do this for async methods)
                // we don't have anything to register continuations with in this case, so just return immediately
                return(task);
            }

            customContext.WorkQueue.ExecuteWorkQueueLoop();

            task.RethrowForCompletedTasks();

            return(task);
        }
    }
Esempio n. 4
0
    /// <summary>
    /// Runs the action inside a message loop and continues looping work items
    /// as long as any asynchronous operations have been registered
    /// </summary>
    public static void Run(Action asyncAction)
    {
        using (SynchronizationContextSwitcher.Capture())
        {
            var customContext = new VoidContext();
            SynchronizationContext.SetSynchronizationContext(customContext);

            // Do an explicit increment/decrement.
            // Our sync context does a check on decrement, to see if there are any
            // outstanding asynchronous operations (async void methods register this correctly).
            // If there aren't any registerd operations, then it will exit the loop
            customContext.OperationStarted();
            try
            {
                asyncAction.Invoke();
            }
            finally
            {
                customContext.OperationCompleted();
            }

            customContext.WorkQueue.ExecuteWorkQueueLoop();
            // ExecuteWorkQueueLoop() has returned. This must indicate that
            // the operation count has fallen back to zero.
        }
    }
Esempio n. 5
0
        /// <summary>
        /// Wraps a <see cref="Task"/> into the Begin method of an APM pattern.
        /// </summary>
        /// <param name="task">The task to wrap.</param>
        /// <param name="callback">The callback method passed into the Begin method of the APM pattern.</param>
        /// <param name="state">The state passed into the Begin method of the APM pattern.</param>
        /// <returns>The asynchronous operation, to be returned by the Begin method of the APM pattern.</returns>
        public static IAsyncResult ToBegin(Task task, AsyncCallback callback, object state)
        {
            var tcs = new TaskCompletionSource <object>(state, TaskCreationOptions.RunContinuationsAsynchronously);

            using (SynchronizationContextSwitcher.NoContext())
                CompleteAsync(task, callback, tcs);
            return(tcs.Task);
        }
Esempio n. 6
0
 public override Task <int> ReadAsync([NotNull] byte[] buffer, int offset, int count, CancellationToken token)
 {
     CheckDisposed();
     return(SynchronizationContextSwitcher.NoContext(async() =>
     {
         count = Math.Min(count, _row.ColumnLen - _row.PosInColumn);
         var read = await _row.Buffer.ReadAllBytes(buffer, offset, count, true, true);
         _row.PosInColumn += read;
         return read;
     }));
 }
Esempio n. 7
0
    /// <summary>
    /// Runs the action inside a message loop and continues pumping messages
    /// as long as any asynchronous operations have been registered
    /// </summary>
    public static void Run(Action asyncAction)
    {
        using (SynchronizationContextSwitcher.Capture())
        {
            Dispatcher      dispatcher = Dispatcher.CurrentDispatcher;
            DispatcherFrame frame      = new DispatcherFrame(exitWhenRequested: true);

            var message = new AsyncActionLaunchMessage(asyncAction, dispatcher, frame);

            // queue up our first message before we run the loop
            dispatcher.BeginInvoke(new Action(message.LaunchMessageImpl));

            // run the actual WPF message loop
            Dispatcher.PushFrame(frame);

            // PushFrame() has returned. This must indicate that
            // the operation count has fallen back to zero.
        }
    }