private static void DoActionItem(ShortcutItem ActiveShortcutItem, int itemIndex, ExtendedScreenshot ActionItemScreenshot) { if (ActiveShortcutItem == null || itemIndex >= ActiveShortcutItem.ActionChain.ActionItems.Count) { Trace.WriteLine("No more action items to execute", string.Format("Program.DoActionItem [{0}]", System.Threading.Thread.CurrentThread.Name)); //todo: Why can't the hook be reinstated on the action thread? Preview.BeginInvoke(new MethodInvoker(() => KeyboardHook.isPaused = false)); IconAnimation.CancelAsync(); return; } IActionItem CurrentActionItem = ActiveShortcutItem.ActionChain.ActionItems[itemIndex]; //don't try and invoke the scrolling screenshot actions if they're the first type in the action chain (eg, solo items for their shortcuts) and there's no active scrolling screenshot happening //at least this solves flashing the icon whenever 'End' key is pressed during normal computer use if (!Program.isTakingScrollingScreenshot && (CurrentActionItem.ActionType == ActionTypes.ContinueScrollingScreenshot || CurrentActionItem.ActionType == ActionTypes.EndScrollingScreenshot) && itemIndex == 0) { return; } KeyboardHook.isPaused = true; Trace.WriteLine(CurrentActionItem.ActionType, string.Format("Program.DoActionItem [{0}]", System.Threading.Thread.CurrentThread.Name)); //todo: figure out a better way to do these exclusions rather than harcoding behavior for scrolling screenshots if (!IconAnimation.IsBusy) { if ((new[] { ActionTypes.ContinueScrollingScreenshot, ActionTypes.EndScrollingScreenshot }.Contains(CurrentActionItem.ActionType) && isTakingScrollingScreenshot) || !new[] { ActionTypes.ContinueScrollingScreenshot, ActionTypes.EndScrollingScreenshot }.Contains(CurrentActionItem.ActionType)) { IconAnimation.RunWorkerAsync(); } } Task.Factory.StartNew <ExtendedScreenshot>(() => CurrentActionItem.Invoke(ActionItemScreenshot)) .ContinueWith(t => DoActionItem(ActiveShortcutItem, itemIndex + 1, t.Result)); }