Пример #1
0
        /// <summary>
        /// 「Kinkaku.jpg.aclgene」ファイルを、仮想ディレクトリ空間に「Subdir」フォルダを作成し、フォルダ内に配置します
        /// </summary>
        /// <param name="loadWorkspaceId"></param>
        /// <returns></returns>
        public static FileInfo CopyVirtualSpaceSubdirectory_Kinkaku_aclgene(long loadWorkspaceId)
        {
            const string subdirName = "Subdir";

            FileInfo virtualSpaceFileInfo;
            Assembly myAssembly = Assembly.GetExecutingAssembly();
            string   path       = Path.GetDirectoryName(myAssembly.Location);
            var      srcFile    = new FileInfo(path + "/Assets/Acl/Kinkaku.jpg.aclgene");

            using (var dbc = new AppDbContext())
            {
                var repo      = new WorkspaceRepository(dbc);
                var workspace = repo.Load(loadWorkspaceId);

                // Subdirフォルダを作成
                Directory.CreateDirectory(Path.Combine(workspace.WorkspacePath, subdirName));

                virtualSpaceFileInfo = new FileInfo(Path.Combine(
                                                        Path.Combine(workspace.WorkspacePath, subdirName)
                                                        , srcFile.Name));
                srcFile.CopyTo(virtualSpaceFileInfo.FullName, true);
            }

            return(virtualSpaceFileInfo);
        }
Пример #2
0
        private SVP.CIL.Domain.Workspace WorkspaceRead(AppDbContext dbc, SVP.CIL.Domain.Workspace target)
        {
            var repo            = new WorkspaceRepository(dbc);
            var workspace       = repo.Load(target.Id);
            var domainWorkspace = Mapper.Map <SVP.CIL.Domain.Workspace>(workspace);

            return(domainWorkspace);
        }
Пример #3
0
        private bool WorkspaceDelete(AppDbContext dbc, SVP.CIL.Domain.Workspace target)
        {
            var repo      = new WorkspaceRepository(dbc);
            var workspace = repo.Load(target.Id);

            repo.Delete(workspace);
            dbc.SaveChanges();
            return(true);
        }
Пример #4
0
        private SVP.CIL.Domain.Workspace WorkspaceUpdate(AppDbContext dbc, SVP.CIL.Domain.Workspace target)
        {
            var repo      = new WorkspaceRepository(dbc);
            var workspace = repo.Load(target.Id);

            Mapper.Map <SVP.CIL.Domain.Workspace, Workspace>(target, workspace);
            repo.Save();
            dbc.SaveChanges();
            var domainWorkspace = Mapper.Map <SVP.CIL.Domain.Workspace>(workspace);

            return(domainWorkspace);
        }
Пример #5
0
        public void Run_UpdateVirtualSpaceAppFlowTest_RenameFileName()
        {
            LOG.Debug("execute method run");

            UpdateVirtualSpaceAppFlowTestSupport.RemoveVirtualFile(1L);
            UpdateVirtualSpaceAppFlowTestSupport.RemovePhysicalFile(1L);
            UpdateVirtualSpaceAppFlowTestSupport.CopyPhysicalSpace_Kinkaku(1L);

            var aclfile = UpdateVirtualSpaceAppFlowTestSupport.CopyVirtualSpace_Kinkaku_aclgene(1L);

            aclfile.MoveTo(Path.Combine(aclfile.DirectoryName, "Kinkaku2.jpg.aclgene"));             //  新しいACLファイル名前にリネームする
            aclfile = new FileInfo(Path.Combine(aclfile.DirectoryName, "Kinkaku2.jpg.aclgene"));

            // ...
            using (var dbc = new AppDbContext())
            {
                var workspace = WorkspaceRepository.Load(dbc, 1L);
                var workflow  = new WorkflowInvoker(new UpdateVirtualSpaceAppFlow());
                workflow.Extensions.Add(new WorkflowExtention(dbc));

                var pstack = new ParameterStack();
                pstack.SetValue("Event", Mogami.Core.Constructions.UpdateVirtualStatusEventType.RENAME);
                pstack.SetValue(ActivityParameterStack.WORKSPACE_FILEPATH, "Kinkaku2.jpg.aclgene");                 // リネーム後のファイル名
                pstack.SetValue(ActivityParameterStack.WORKSPACE, workspace);

                var results = workflow.Invoke(new Dictionary <string, object>
                {
                    { "ParameterStack", pstack }
                });

                dbc.SaveChanges();
            }

            using (var dbc = new AppDbContext())
            {
                var filemapinginfoRepository = new FileMappingInfoRepository(dbc);
                var entity = filemapinginfoRepository.Load(1L);

                var workspace = WorkspaceRepository.Load(dbc, 1L);

                // エンティティの値が変わっていることの確認
                Assert.AreEqual("Kinkaku2.jpg", entity.MappingFilePath);

                // 物理ディレクトリ空間での、ファイル名称が変更していることの確認
                var physicalFileInfo = new FileInfo(Path.Combine(workspace.PhysicalPath, "Kinkaku2.jpg"));
                Assert.IsTrue(physicalFileInfo.Exists);
            }
        }
Пример #6
0
        /// <summary>
        /// テスト用ファイルを、物理ディレクトリ空間に配置します
        /// </summary>
        /// <param name="loadWorkspaceId">ワークスペース</param>
        /// <returns>物理ディレクトリ空間でのファイル情報</returns>
        public static FileInfo CopyPhysicalSpace_Kinkaku(long loadWorkspaceId)
        {
            FileInfo physicalSpaceFileInfo;
            Assembly myAssembly = Assembly.GetExecutingAssembly();
            string   path       = Path.GetDirectoryName(myAssembly.Location);
            var      srcFile    = new FileInfo(path + "/Assets/Image/Kinkaku.jpg");

            using (var dbc = new AppDbContext())
            {
                var repo      = new WorkspaceRepository(dbc);
                var workspace = repo.Load(loadWorkspaceId);

                physicalSpaceFileInfo = new FileInfo(Path.Combine(workspace.PhysicalPath, srcFile.Name));
                srcFile.CopyTo(physicalSpaceFileInfo.FullName, true);
            }

            return(physicalSpaceFileInfo);
        }
Пример #7
0
        public void Run_UpdateVirtualSpaceAppFlowTest_DeleteFileName()
        {
            UpdateVirtualSpaceAppFlowTestSupport.RemoveVirtualFile(1L);
            UpdateVirtualSpaceAppFlowTestSupport.RemovePhysicalFile(1L);
            UpdateVirtualSpaceAppFlowTestSupport.CopyPhysicalSpace_Kinkaku(1L);

            var aclfile = UpdateVirtualSpaceAppFlowTestSupport.CopyVirtualSpace_Kinkaku_aclgene(1L);

            aclfile.Delete();


            using (var dbc = new AppDbContext())
            {
                var workspace = WorkspaceRepository.Load(dbc, 1L);
                var workflow  = new WorkflowInvoker(new UpdateVirtualSpaceAppFlow());
                workflow.Extensions.Add(new WorkflowExtention(dbc));

                var pstack = new ParameterStack();
                pstack.SetValue("Event", Mogami.Core.Constructions.UpdateVirtualStatusEventType.DELETE);
                pstack.SetValue(ActivityParameterStack.WORKSPACE_FILEPATH, "Kinkaku.jpg.aclgene");                 // 削除したファイル
                pstack.SetValue(ActivityParameterStack.WORKSPACE, workspace);
                pstack.SetValue("WF_DeleteAclHash", "Test");

                var results = workflow.Invoke(new Dictionary <string, object>
                {
                    { "ParameterStack", pstack }
                });

                dbc.SaveChanges();
            }

            using (var dbc = new AppDbContext())
            {
                var workspace = WorkspaceRepository.Load(dbc, 1L);

                // 物理ファイルが削除されていることを確認する
                var physicalFileInfo = new FileInfo(Path.Combine(workspace.PhysicalPath, "Kinkaku.jpg"));
                Assert.IsFalse(physicalFileInfo.Exists);

                var entity = FileMappingInfoRepository.Load(dbc, 1L);
                Assert.IsNull(entity);
            }
        }
Пример #8
0
        /// <summary>
        /// 仮想ディレクトリ空間のすべてのファイルを削除します
        /// </summary>
        /// <param name="loadWorkspaceId">ワークスペース</param>
        public static void RemoveVirtualFile(long loadWorkspaceId)
        {
            using (var dbc = new AppDbContext())
            {
                var repo      = new WorkspaceRepository(dbc);
                var workspace = repo.Load(loadWorkspaceId);

                var dirInfo = new DirectoryInfo(workspace.WorkspacePath);
                while (dirInfo.Exists)
                {
                    Directory.Delete(workspace.WorkspacePath, true);
                    dirInfo = new DirectoryInfo(workspace.WorkspacePath);
                    Thread.Sleep(100);
                }

                while (!dirInfo.Exists)
                {
                    Directory.CreateDirectory(workspace.WorkspacePath);
                    dirInfo = new DirectoryInfo(workspace.WorkspacePath);
                    Thread.Sleep(100);
                }
            }
        }
        /// <summary>
        /// 定期的に、ファイル操作があったファイルに対するVFS処理を行う
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        async void OnIndexTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (this.IsSuspendIndex)
            {
                return;                                  // サスペンド時はインデックス生成処理はスキップする
            }
            // インデックス生成処理中は、このメソッドを呼び出すタイマーは停止しておきます。
            var timer = sender as System.Timers.Timer;

            timer.Enabled = false;

            LOG.Info("タイマー処理の実行");


            // ディレクトリ削除イベントが発生している場合、
            // 削除したディレクトリに含まれていたファイルを、削除したパスから見つけ出して削除処理を行うキューに追加する
            lock (sameDirectoryOperation_Locker)
            {
                if (sameDirectoryOperation_Name != "")
                {
                    sameDirectoryOperation_Name = "";
                    var relativeDirPath = _Workspace.TrimWorekspacePath(sameDirectoryOperation_FullPath, false);

                    /*
                     * using (var dbc = new AppDbContext())
                     * {
                     *      var repo = new FileMappingInfoRepository(dbc);
                     *      foreach (var prop in repo.FindBy(p => p.MappingFilePath.StartsWith(relativeDirPath)))
                     *      {
                     *              var fileUpdateQueueItem = new FileUpdateQueueItem { Target = new FileInfo(Path.Combine(_Workspace.WorkspacePath, prop.MappingFilePath + ".aclgene")) };
                     *              fileUpdateQueueItem.Recents.Add(new RecentInfo { EventType = WatcherChangeTypes.Deleted });
                     *              _UpdatesWatchFiles.AddOrUpdate(prop.MappingFilePath, fileUpdateQueueItem, (_key, _value) => fileUpdateQueueItem);
                     *      }
                     * }
                     */
                }
            }

            //
            foreach (var @pair in _UpdatesWatchFiles.ToList())
            {
                // 最後のファイル監視状態から、一定時間経過している場合のみ処理を行う。
                var @diff = DateTime.Now - @pair.Value.LastUpdate;

                if (@diff.Seconds >= 10)                 // 10秒 以上経過
                {
                    FileUpdateQueueItem item;            // work
                    if (_UpdatesWatchFiles.TryRemove(@pair.Key, out item))
                    {
                        var @lastItem = item.Recents.LastOrDefault();

                        // NOTE: UpdateVirtualSpaceFlowワークフローを呼び出す
                        LOG.InfoFormat("ワークフロー実行 [{1}] 対象ファイルパス={0}", item.Target.FullName, @lastItem.EventType);

                        // ワークフロー処理中に発生するファイル更新イベントにより、更新キューに項目が追加されてしまうことを防ぐため、
                        // 処理中のファイルを更新キューから除外するための除外リストに、処理中のファイルを追加する。
                        //
                        // ※処理中のファイルがACLファイル以外の場合、対象ファイルのACLファイル名も除外リストに追加する
                        _IgnoreUpdateFiles.Enqueue(item.Target.FullName);
                        if (item.Target.Extension != ".aclgene")
                        {
                            _IgnoreUpdateFiles.Enqueue(item.Target.FullName + ".aclgene");
                        }

                        try
                        {
                            using (var dbc = new AppDbContext())
                            {
                                var workspace = WorkspaceRepository.Load(dbc, _Workspace.Id);
                                if (workspace == null)
                                {
                                    workspace = _Workspace;
                                }

                                // 処理対象のファイルがACLファイルか、物理ファイルかで処理を切り分けます
                                // ■ACLファイルの場合
                                //    リネーム更新イベントに対応します。
                                // ■物理ファイルの場合
                                //    リネーム更新イベントも、UPDATEイベントとして処理します。
                                if (item.Target.Extension == ".aclgene")
                                {
                                    var fileNameWithputExtension = item.Target.Name.Replace(item.Target.Extension, "");
                                    switch (@lastItem.EventType)
                                    {
                                    case WatcherChangeTypes.Renamed:
                                        file_rename_acl(dbc, item, workspace);
                                        break;

                                    case WatcherChangeTypes.Changed:
                                    case WatcherChangeTypes.Created:
                                        file_create_acl(dbc, item, workspace);
                                        break;

                                    case WatcherChangeTypes.Deleted:
                                        file_remove_acl(dbc, item, workspace);
                                        break;
                                    }
                                }
                                else
                                {
                                    if (File.Exists(item.Target.FullName))
                                    {
                                        switch (@lastItem.EventType)
                                        {
                                        case WatcherChangeTypes.Renamed:
                                        case WatcherChangeTypes.Changed:
                                        case WatcherChangeTypes.Created:
                                            file_create_normal(dbc, item, workspace);
                                            break;

                                        case WatcherChangeTypes.Deleted:
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        LOG.InfoFormat("「{0}」は存在しない物理ファイルのため、処理をスキップします。", item.Target.FullName);
                                    }
                                }

                                dbc.SaveChanges();
                            }
                        }
                        catch (Exception expr)
                        {
                            LOG.ErrorFormat("タイマー処理時エラー = {0}", expr.Message);
                        }

                        // 処理を終了したファイルを、除外リストから削除します
                        string ignoreUpdateFile;
                        _IgnoreUpdateFiles.TryDequeue(out ignoreUpdateFile);
                        if (item.Target.Extension != ".aclgene")
                        {
                            _IgnoreUpdateFiles.TryDequeue(out ignoreUpdateFile);
                        }
                    }
                }

                // [CPU使用率に対するループ遅延を行う]
                var cpuPer = _CpuCounter.NextValue();
                if (cpuPer > 90.0)
                {
                    await Task.Delay(100);                     // 100msec待機
                }
                else if (cpuPer > 30.0)
                {
                    //await Task.Delay(10); // 10msec待機
                }
            }

            timer.Enabled = true;
        }
Пример #10
0
        /// <summary>
        /// インデックス作成処理を一定間隔で行います
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        async void OnIndexTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (this.IsSuspendIndex)
            {
                return;                                  // サスペンド時はインデックス生成処理はスキップする
            }
            // インデックス生成処理中は、このメソッドを呼び出すタイマーは停止しておきます。
            var timer = sender as System.Timers.Timer;

            timer.Enabled = false;

            LOG.Info("タイマー処理の実行");

            // ディレクトリ削除イベントが発生している場合、
            // 削除したディレクトリに含まれていたファイルを、削除したパスから見つけ出して削除処理を行うキューに追加する
            lock (sameDirectoryOperation_Locker)
            {
                if (sameDirectoryOperation_Name != "")
                {
                    sameDirectoryOperation_Name = "";
                    var relativeDirPath = _Workspace.TrimWorekspacePath(sameDirectoryOperation_FullPath, false);
                    using (var dbc = new AppDbContext())
                    {
                        var repo = new FileMappingInfoRepository(dbc);
                        foreach (var prop in repo.FindBy(p => p.MappingFilePath.StartsWith(relativeDirPath)))
                        {
                            var fileUpdateQueueItem = new FileUpdateQueueItem {
                                Target = new FileInfo(Path.Combine(_Workspace.WorkspacePath, prop.MappingFilePath + ".aclgene"))
                            };
                            fileUpdateQueueItem.Recents.Add(new RecentInfo {
                                EventType = WatcherChangeTypes.Deleted
                            });
                            _UpdatesWatchFiles.AddOrUpdate(prop.MappingFilePath, fileUpdateQueueItem, (_key, _value) => fileUpdateQueueItem);
                        }
                    }
                }
            }

            //
            foreach (var @pair in _UpdatesWatchFiles.ToList())
            {
                // 最後のファイル監視状態から、一定時間経過している場合のみ処理を行う。
                var @diff = DateTime.Now - @pair.Value.LastUpdate;

                if (@diff.Seconds >= 10)                 // 10秒 以上経過
                {
                    FileUpdateQueueItem item;            // work
                    if (_UpdatesWatchFiles.TryRemove(@pair.Key, out item))
                    {
                        var @lastItem = item.Recents.LastOrDefault();

                        // NOTE: UpdateVirtualSpaceFlowワークフローを呼び出す
                        LOG.InfoFormat("ワークフロー実行 [{1}] 対象ファイルパス={0}", item.Target.FullName, @lastItem.EventType);

                        // ワークフロー処理中に発生するファイル更新イベントにより、更新キューに項目が追加されてしまうことを防ぐため、
                        // 処理中のファイルを更新キューから除外するための除外リストに、処理中のファイルを追加する。
                        //
                        // ※処理中のファイルがACLファイル以外の場合、対象ファイルのACLファイル名も除外リストに追加する
                        _IgnoreUpdateFiles.Enqueue(item.Target.FullName);
                        if (item.Target.Extension != ".aclgene")
                        {
                            _IgnoreUpdateFiles.Enqueue(item.Target.FullName + ".aclgene");
                        }

                        try
                        {
                            using (var dbc = new AppDbContext())
                            {
                                var workspace = WorkspaceRepository.Load(dbc, _Workspace.Id);
                                var workflow  = new WorkflowInvoker(new UpdateVirtualSpaceAppFlow());
                                workflow.Extensions.Add(new WorkflowExtention(dbc));
                                var pstack = new ParameterStack();

                                // 処理対象のファイルがACLファイルか、物理ファイルかで処理を切り分けます
                                // ■ACLファイルの場合
                                //    リネーム更新イベントに対応します。
                                // ■物理ファイルの場合
                                //    リネーム更新イベントも、UPDATEイベントとして処理します。
                                if (item.Target.Extension == ".aclgene")
                                {
                                    var fileNameWithputExtension = item.Target.Name.Replace(item.Target.Extension, "");
                                    switch (@lastItem.EventType)
                                    {
                                    case WatcherChangeTypes.Renamed:
                                        pstack.SetValue("Event", Mogami.Core.Constructions.UpdateVirtualStatusEventType.RENAME);
                                        pstack.SetValue(ActivityParameterStack.WORKSPACE_FILEINFO, item.Target);
                                        pstack.SetValue(ActivityParameterStack.WORKSPACE_FILEPATH, item.Target.Name);                                                 // リネーム後のファイル名
                                        pstack.SetValue(ActivityParameterStack.WORKSPACE, workspace);

                                        var results_renamed = workflow.Invoke(new Dictionary <string, object>
                                        {
                                            { "ParameterStack", pstack },
                                            //{"EventType", UpdateVirtualStatusEventType.RENAME},
                                            //{"Target", item.Target},
                                            //{"BeforeRenameName",item.OldRenameNamePath},
                                            //{"Workspace", workspace}
                                        });
                                        break;

                                    case WatcherChangeTypes.Changed:
                                    case WatcherChangeTypes.Created:
                                        var aclfileLocalPath = workspace.TrimWorekspacePath(item.Target.FullName, false);
                                        pstack.SetValue("Event", Mogami.Core.Constructions.UpdateVirtualStatusEventType.UPDATE);
                                        pstack.SetValue(ActivityParameterStack.WORKSPACE_FILEINFO, item.Target);
                                        pstack.SetValue(ActivityParameterStack.WORKSPACE_FILEPATH, aclfileLocalPath);                                                 // 移動後のファイルパス
                                        pstack.SetValue(ActivityParameterStack.WORKSPACE, workspace);
                                        var results_changed = workflow.Invoke(new Dictionary <string, object>
                                        {
                                            { "ParameterStack", pstack },
                                            //{"EventType", UpdateVirtualStatusEventType.UPDATE},
                                            //{"Target", item.Target},
                                            //{"Workspace", workspace}
                                        });
                                        break;

                                    case WatcherChangeTypes.Deleted:
                                        var aclfileLocalPath_Delete = workspace.TrimWorekspacePath(item.Target.FullName, false);
                                        pstack.SetValue("Event", Mogami.Core.Constructions.UpdateVirtualStatusEventType.DELETE);
                                        pstack.SetValue(ActivityParameterStack.WORKSPACE_FILEINFO, item.Target);
                                        pstack.SetValue(ActivityParameterStack.WORKSPACE_FILEPATH, aclfileLocalPath_Delete);                                                 // 削除したファイル
                                        pstack.SetValue(ActivityParameterStack.WORKSPACE, workspace);
                                        pstack.SetValue("WF_DeleteAclMappingFilePath", fileNameWithputExtension);

                                        var results_deleted = workflow.Invoke(new Dictionary <string, object>
                                        {
                                            { "ParameterStack", pstack },
                                            //{"EventType", UpdateVirtualStatusEventType.DELETE},
                                            //{"Target", item.Target},
                                            //{"DeleteAclHash", @pair.Key},
                                            //{"Workspace", workspace}
                                        });
                                        break;
                                    }
                                }
                                else
                                {
                                    if (File.Exists(item.Target.FullName))
                                    {
                                        switch (@lastItem.EventType)
                                        {
                                        case WatcherChangeTypes.Renamed:
                                        case WatcherChangeTypes.Changed:
                                        case WatcherChangeTypes.Created:
                                            var aclfileLocalPath_Update = workspace.TrimWorekspacePath(item.Target.FullName, false);
                                            pstack.SetValue("Event", Mogami.Core.Constructions.UpdateVirtualStatusEventType.UPDATE);
                                            pstack.SetValue(ActivityParameterStack.WORKSPACE_FILEINFO, item.Target);
                                            pstack.SetValue(ActivityParameterStack.WORKSPACE_FILEPATH, aclfileLocalPath_Update);                                                     // 削除したファイル
                                            pstack.SetValue(ActivityParameterStack.WORKSPACE, workspace);

                                            var results_changed = workflow.Invoke(new Dictionary <string, object>
                                            {
                                                { "ParameterStack", pstack },
                                                //{"EventType", UpdateVirtualStatusEventType.UPDATE},
                                                //{"Target", item.Target},
                                                //{"Workspace", workspace}
                                            });
                                            break;

                                        case WatcherChangeTypes.Deleted:
                                            var aclfileLocalPath_Delete = workspace.TrimWorekspacePath(item.Target.FullName, false);
                                            pstack.SetValue("Event", Mogami.Core.Constructions.UpdateVirtualStatusEventType.DELETE);
                                            pstack.SetValue(ActivityParameterStack.WORKSPACE_FILEINFO, item.Target);
                                            pstack.SetValue(ActivityParameterStack.WORKSPACE_FILEPATH, aclfileLocalPath_Delete);                                                     // 削除したファイル
                                            pstack.SetValue(ActivityParameterStack.WORKSPACE, workspace);

                                            var results_deleted = workflow.Invoke(new Dictionary <string, object>
                                            {
                                                { "ParameterStack", pstack },
                                                //{"EventType", UpdateVirtualStatusEventType.DELETE},
                                                //{"Target", item.Target},
                                                //{"Workspace", workspace}
                                            });
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        LOG.InfoFormat("「{0}」は存在しない物理ファイルのため、処理をスキップします。", item.Target.FullName);
                                    }
                                }

                                dbc.SaveChanges();
                            }
                        }
                        catch (Exception expr)
                        {
                            LOG.ErrorFormat("タイマー処理時エラー = {0}", expr.Message);
                        }

                        // 処理を終了したファイルを、除外リストから削除します
                        string ignoreUpdateFile;
                        _IgnoreUpdateFiles.TryDequeue(out ignoreUpdateFile);
                        if (item.Target.Extension != ".aclgene")
                        {
                            _IgnoreUpdateFiles.TryDequeue(out ignoreUpdateFile);
                        }
                    }
                }

                // [CPU使用率に対するループ遅延を行う]
                var cpuPer = _CpuCounter.NextValue();
                if (cpuPer > 90.0)
                {
                    await Task.Delay(100);                     // 100msec待機
                }
                else if (cpuPer > 30.0)
                {
                    //await Task.Delay(10); // 10msec待機
                }
            }

            timer.Enabled = true;
        }