public void StartExecution(EventWaitHandle wainHandle = null) { ExecutionException = null; if (ThreadPool == null) { foreach (Action action in mActionGroups.SelectMany(ag => ag)) { action(); } } else { List <List <Action> > actionGroups = mActionGroups.ToList(); if (wainHandle != null) { actionGroups.Add(new List <Action> { () => { try { wainHandle.Set(); } catch { } } }); } IWorkItemsGroup[] wigs = actionGroups.Select(ag => ThreadPool.CreateWorkItemsGroup(ag.Count, new WIGStartInfo { WorkItemPriority = WorkItemPriority })).ToArray(); // make wig chain via on-idle event for (int i = wigs.Length - 2; i >= 0; i--) { int j = i + 1; wigs[i].OnIdle += g => { if (ExecutionException == null) { QueueWorkItems(wigs[j], actionGroups[j]); } else { if (wainHandle != null) { try { wainHandle.Set(); } catch { } } } }; } // start off by running first member of the chain QueueWorkItems(wigs[0], actionGroups[0]); } }