public int CfRunLoopStart()
        {
            //還在執行中, 不接受重新執行
            if (this.RunningTask != null && this.RunningTask.Status < TaskStatus.RanToCompletion)
            {
                return(1);
            }

            //需要重複確認機台的功能是活著的, 因此使用RunLoop重複運作
            this.RunningTask = CtkTask.RunLoop(() =>
            {
                try
                {
                    this.CfRunOnce();
                }
                catch (Exception ex)
                {
                    //Task root method 需要try/catch: 已經到最上層, 就必須捕抓->寫log, 否則就看不到這個例外
                    CtkLog.WriteNs(this, ex);
                }
                Thread.Sleep(5 * 1000);
                return(!this.disposed);//d20201210 機台仍舊要持續運作
            });

            return(0);
        }
        public void UpdateFromFolder(string folder = null)
        {
            this.Folder = folder == null ? this.Folder : folder;//Folder不得為空, 所以傳空值就保留原本的

            this.LastUpdate = DateTime.Now;

            //記錄現有的
            var orignalConfigs = new Dictionary <String, Boolean>();

            foreach (var name in this.Keys)
            {
                orignalConfigs[name] = false;
            }

            var di = new DirectoryInfo(this.Folder);

            if (!di.Exists)
            {
                di.Create();
            }
            foreach (var fi in di.GetFiles())
            {
                if (this.Filter != null)
                {
                    if (!Filter(fi.Name))
                    {
                        continue;                  //沒通過就不加入
                    }
                }
                try
                {
                    var config = CtkUtil.LoadXmlFromFileOrDefault <T>(fi.FullName);
                    this[fi.Name] = config;
                }
                catch (Exception ex) { CtkLog.WriteNs(this, ex.Message); }

                //更新存在的
                orignalConfigs[fi.Name] = true;
            }


            //移除沒更新到的
            foreach (var kv in orignalConfigs)
            {
                if (kv.Value)
                {
                    continue;
                }
                this.Remove(kv.Key);
            }
        }