/// <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. } }
/// <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 (InstallerAndRestorer.Install()) { // InstallerAndRestorer ensures the WinForms context is installed // capture that WinFormsContext var winFormsContext = SynchronizationContext.Current; // wrap the WinForms context in our own decorator context and install that var asyncVoidContext = new AsyncVoidSyncContext(winFormsContext); SynchronizationContext.SetSynchronizationContext(asyncVoidContext); // queue up the first message before we start running the loop var message = new AsyncActionLaunchMessage(asyncAction, asyncVoidContext); asyncVoidContext.Post(message.LaunchMessageImpl, state: null); // run the actual WinForms message loop Application.Run(); } }