public static void StartRunningProcesses()
    {
        if (running)
        {
            throw new InvalidOperationException("ProcessLogic is running");
        }

        using (ExecutionContext.SuppressFlow())
            Task.Factory.StartNew(() =>
            {
                var database = Schema.Current.Table(typeof(ProcessEntity)).Name.Schema?.Database;

                SystemEventLogLogic.Log("Start ProcessRunner");
                ExceptionEntity?exception = null;
                using (AuthLogic.Disable())
                {
                    try
                    {
                        running = true;

                        (from p in Database.Query <ProcessEntity>()
                         where p.IsMine() && (p.State == ProcessState.Executing || p.State == ProcessState.Suspending || p.State == ProcessState.Suspended) ||
                         p.IsShared() && p.State == ProcessState.Suspended
                         select p).SetAsQueued();

                        CancelNewProcesses = new CancellationTokenSource();

                        autoResetEvent.Set();

                        timerNextExecution = new Timer(ob => WakeUp("TimerNextExecution", null), // main timer
                                                       null,
                                                       Timeout.Infinite,
                                                       Timeout.Infinite);

                        if (!CacheLogic.WithSqlDependency)
                        {
                            timerPeriodic = new Timer(ob => WakeUp("TimerPeriodic", null), null, PoolingPeriodMilliseconds, PoolingPeriodMilliseconds);
                        }

                        while (autoResetEvent.WaitOne())
                        {
                            if (CancelNewProcesses.IsCancellationRequested)
                            {
                                return;
                            }

                            using (HeavyProfiler.Log("PWL", () => "Process Runner"))
                            {
                                (from p in Database.Query <ProcessEntity>()
                                 where p.State == ProcessState.Planned && p.PlannedDate <= Clock.Now
                                 select p).SetAsQueued();

                                var list = Database.Query <ProcessEntity>()
                                           .Where(p => p.IsMine() || p.IsShared())
                                           .Where(p => p.State == ProcessState.Planned)
                                           .Select(p => p.PlannedDate)
                                           .ToListWakeup("Planned dependency");

                                SetNextPannedExecution(list.Min());

                                lock (executing)
                                {
                                    int remaining = MaxDegreeOfParallelism - executing.Count;

                                    if (remaining > 0)
                                    {
                                        retry:
                                        var queued = Database.Query <ProcessEntity>()
                                                     .Where(p => p.State == ProcessState.Queued)
                                                     .Where(p => p.IsMine() || p.IsShared())
                                                     .Select(a => new { Process = a.ToLite(), a.QueuedDate, a.MachineName })
                                                     .ToListWakeup("Planned dependency");

                                        var afordable = queued
                                                        .OrderByDescending(p => p.MachineName == Environment.MachineName)
                                                        .OrderBy(a => a.QueuedDate)
                                                        .Take(remaining).ToList();

                                        var taken = afordable.Where(p => p.MachineName == ProcessEntity.None).Select(a => a.Process).ToList();

                                        if (taken.Any())
                                        {
                                            using (var tr = Transaction.ForceNew())
                                            {
                                                Database.Query <ProcessEntity>()
                                                .Where(p => taken.Contains(p.ToLite()) && p.MachineName == ProcessEntity.None)
                                                .UnsafeUpdate()
                                                .Set(p => p.MachineName, p => Environment.MachineName)
                                                .Set(p => p.ApplicationName, p => Schema.Current.ApplicationName)
                                                .Execute();

                                                tr.Commit();
                                            }


                                            goto retry;
                                        }


                                        foreach (var pair in afordable)
                                        {
                                            ProcessEntity pro = pair.Process !.RetrieveAndRemember();

                                            IProcessAlgorithm algorithm = ProcessLogic.GetProcessAlgorithm(pro.Algorithm);

                                            ExecutingProcess executingProcess = new ExecutingProcess(algorithm, pro);

                                            executing.Add(pro.ToLite(), executingProcess);

                                            executingProcess.TakeForThisMachine();

                                            using (ExecutionContext.SuppressFlow())
                                                Task.Run(() =>
                                                {
                                                    try
                                                    {
                                                        executingProcess.Execute();
                                                    }
                                                    catch (Exception ex)
                                                    {
                                                        try
                                                        {
                                                            ex.LogException(edn =>
                                                            {
                                                                edn.ControllerName = "ProcessWorker";
                                                                edn.ActionName     = executingProcess.CurrentProcess.ToLite().Key();
                                                            });
                                                        }
                                                        catch { }
                                                    }
                                                    finally
                                                    {
                                                        lock (executing)
                                                        {
                                                            executing.Remove(pro.ToLite());
                                                            WakeUp("Process ended", null);
                                                        }
                                                    }
                                                });
                                        }

                                        var suspending = Database.Query <ProcessEntity>()
                                                         .Where(p => p.State == ProcessState.Suspending)
                                                         .Where(p => p.IsMine())
                                                         .Select(a => a.ToLite())
                                                         .ToListWakeup("Suspending dependency");

                                        foreach (var s in suspending)
                                        {
                                            ExecutingProcess execProc = executing.GetOrThrow(s);

                                            if (execProc.CurrentProcess.State != ProcessState.Finished)
                                            {
                                                execProc.CurrentProcess = s.RetrieveAndRemember();
                                                execProc.CancelationSource.Cancel();
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    catch (ThreadAbortException)
                    {
                        //Ignore
                    }
                    catch (Exception e)
                    {
                        try
                        {
                            exception = e.LogException(edn =>
                            {
                                edn.ControllerName = "ProcessWorker";
                                edn.ActionName     = "MainLoop";
                            });
                        }
                        catch { }
                    }
                    finally
                    {
                        lock (executing)
                            executing.Clear();

                        SystemEventLogLogic.Log("Stop ProcessRunner", exception);

                        running = false;
                    }
                }
            }, TaskCreationOptions.LongRunning);
    }