/// <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); } }
/// <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 (InstallerAndRestorer.Install()) { // InstallerAndRestorer ensures the WinForms context is installed var winFormsContext = SynchronizationContext.Current; var message = new TaskFunctionLaunchMessage(function, winFormsContext); // queue up our first message before we run the loop winFormsContext.Post(message.LaunchMessageImpl, state: null); // run the actual WinForms message loop Application.Run(); if (message.ReturnedTask != null) { message.ReturnedTask.RethrowForCompletedTasks(); } return(message.ReturnedTask); } }