DbgProcessImpl GetProcess_NoLock(DbgProcessImpl?current, DbgProcessImpl @default)
        {
            if (current is null)
            {
                return(@default);
            }
            switch (current.State)
            {
            case DbgProcessState.Running:
                var runtime = current.CurrentRuntime.Current;
                var engine  = current.TryGetEngine(runtime);
                lock (lockObj) {
                    var info = TryGetEngineInfo_NoLock(engine);
                    if (info?.DelayedIsRunning != false)
                    {
                        return(@default);
                    }
                }
                return(current);

            case DbgProcessState.Paused: return(current);

            case DbgProcessState.Terminated: return(@default);

            default: throw new InvalidOperationException();
            }
        }
        void SetCurrentProcess_DbgThread(DbgProcessImpl newProcess)
        {
            Dispatcher.VerifyAccess();
            if (newProcess is null || newProcess.State != DbgProcessState.Paused)
            {
                return;
            }

            DbgCurrentObjectChangedEventArgs <DbgProcess> processEventArgs;
            DbgCurrentObjectChangedEventArgs <DbgRuntime> runtimeEventArgs;
            DbgCurrentObjectChangedEventArgs <DbgThread>  threadEventArgs;

            lock (lockObj) {
                var newCurrentProcess = new CurrentObject <DbgProcessImpl>(newProcess, dbgCurrentProcess.currentProcess.Break);
                var newCurrentRuntime = newProcess.CurrentRuntime;
                var newCurrentThread  = newCurrentRuntime.Current?.CurrentThread ?? default;
                processEventArgs = new DbgCurrentObjectChangedEventArgs <DbgProcess>(currentChanged: dbgCurrentProcess.currentProcess.Current != newCurrentProcess.Current, breakChanged: dbgCurrentProcess.currentProcess.Break != newCurrentProcess.Break);
                runtimeEventArgs = new DbgCurrentObjectChangedEventArgs <DbgRuntime>(currentChanged: dbgCurrentRuntime.currentRuntime.Current != newCurrentRuntime.Current, breakChanged: dbgCurrentRuntime.currentRuntime.Break != newCurrentRuntime.Break);
                threadEventArgs  = new DbgCurrentObjectChangedEventArgs <DbgThread>(currentChanged: dbgCurrentThread.currentThread.Current != newCurrentThread.Current, breakChanged: dbgCurrentThread.currentThread.Break != newCurrentThread.Break);
                dbgCurrentProcess.currentProcess = newCurrentProcess;
                dbgCurrentRuntime.currentRuntime = newCurrentRuntime;
                dbgCurrentThread.currentThread   = newCurrentThread;
            }
            RaiseCurrentObjectEvents_DbgThread(processEventArgs, runtimeEventArgs, threadEventArgs);
        }