using Dicom.IO; using Dicom.Network; using System; using System.IO; using System.Threading; using System.Threading.Tasks; using Vinno.FIS.Sonopost.Common; using Vinno.FIS.Sonopost.Features.Dicom; using Vinno.FIS.Sonopost.Managers.Interfaces; using Vinno.FIS.Sonopost.Settings; using Vinno.IUS.Common.Log; namespace Vinno.FIS.Sonopost.Managers { internal class DicomServerManager : SonopostManager, IDicomServerManager { private readonly IRemedicalManager _remedicalManager; private IDicomServer _server; private bool _dicomEnabled; private string _dicomTitle; private int _dicomPort; private int _dicomTempFileDays; private bool _isRunning => _server?.IsListening ?? false; private ManualResetEvent _manualResetEvent = new ManualResetEvent(false); private CancellationTokenSource _tokenSource; private Task _task; public DicomServerManager() { _remedicalManager = AppManager.Instance.GetManager(); TemporaryFile.StoragePath = Path.Combine(SonopostConstants.DataFolder, SonopostConstants.TempFiles); _dicomEnabled = SonopostUserDefinedSettings.Instance.DicomSetting.UseDicomService; _dicomTitle = SonopostUserDefinedSettings.Instance.DicomSetting.DicomTitile; _dicomPort = SonopostUserDefinedSettings.Instance.DicomSetting.DicomPort; _dicomTempFileDays = SonopostUserDefinedSettings.Instance.DicomSetting.TempFileDays; Start(); CheckOverDueFile(); } private void Start() { var port = SonopostUserDefinedSettings.Instance.DicomSetting.DicomPort; if (_dicomEnabled && !_isRunning) { _server = DicomServer.Create(port, logger: new DicomLog()); if (_isRunning) { Logger.WriteLineInfo("Dicom server started."); _manualResetEvent.Reset(); } else { Logger.WriteLineWarn("Dicom server start failed."); } } } private void Stop() { if (_server != null) { _server.Stop(); _server.Dispose(); _server = null; Logger.WriteLineInfo("Dicom server Stoped."); } _tokenSource?.Cancel(); _manualResetEvent.Set(); try { _task?.Wait(1000);//因Task在Wait过程中Cancel有几率会出错 } catch { } } public void ChangeValue() { var dicomEnabled = SonopostUserDefinedSettings.Instance.DicomSetting.UseDicomService; var dicomTitle = SonopostUserDefinedSettings.Instance.DicomSetting.DicomTitile; var dicomPort = SonopostUserDefinedSettings.Instance.DicomSetting.DicomPort; var dicomTempFileDays = SonopostUserDefinedSettings.Instance.DicomSetting.TempFileDays; if (_dicomEnabled != dicomEnabled || _dicomTitle != dicomTitle || _dicomPort != dicomPort || _dicomTempFileDays != dicomTempFileDays) { _dicomEnabled = dicomEnabled; _dicomTitle = dicomTitle; _dicomPort = dicomPort; _dicomTempFileDays = dicomTempFileDays; Stop(); Start(); CheckOverDueFile(); } } private void CheckOverDueFile() { var tempFileDays = SonopostUserDefinedSettings.Instance.DicomSetting.TempFileDays; if (tempFileDays > 0) { _tokenSource = new CancellationTokenSource(); _task = Task.Run(() => { while (!_tokenSource.IsCancellationRequested) { try { var originalDicom = Path.Combine(SonopostConstants.DataFolder, SonopostConstants.OriginalDicomFolder); var originalVid = Path.Combine(SonopostConstants.DataFolder, SonopostConstants.OriginalVidFolder); var tempFiles = Path.Combine(SonopostConstants.DataFolder, SonopostConstants.TempFiles); var vinnoDicom = Path.Combine(SonopostConstants.DataFolder, SonopostConstants.VinnoDicomFolder); Logger.WriteLineInfo($"DicomServerManager Start Delete OverDue Files,TempFileDays:{tempFileDays}"); DeleteOverDueFiles(originalDicom, tempFileDays); DeleteOverDueFiles(originalVid, tempFileDays); DeleteOverDueFiles(tempFiles, tempFileDays); DeleteOverDueFiles(vinnoDicom, tempFileDays); DeletetOverDueRecord(tempFileDays); _remedicalManager.DeleteOverDueRecords(tempFileDays); Logger.WriteLineInfo($"DicomServerManager Start Delete OverDue Files"); } catch (Exception ex) { Logger.WriteLineError($"Delete Overdue file fail:{ex}"); } finally { _manualResetEvent.WaitOne(TimeSpan.FromHours(1)); } } }, _tokenSource.Token); } } private void DeletetOverDueRecord(int tempFileDays) { var failList = DicomUploadContextOperator.Instance.GetAll(); foreach (var failItem in failList) { if (DateTime.Now - failItem.CreateTime >= TimeSpan.FromDays(tempFileDays)) { DicomUploadContextOperator.Instance.DeleteById(failItem.Id); } } } private void DeleteOverDueFiles(string path, int tempFileDays) { if (!Directory.Exists(path)) return; var files = Directory.GetFiles(path); foreach (var file in files) { FileInfo fileInfo = new FileInfo(file); if (DateTime.Now - fileInfo.CreationTime >= TimeSpan.FromDays(tempFileDays)) { fileInfo.Delete(); } } var directories = Directory.GetDirectories(path); foreach (var dir in directories) { DeleteOverDueFiles(dir, tempFileDays); } } public override void DoDispose() { try { Stop(); } catch (Exception ex) { Logger.WriteLineError($"DicomServerManager DoDispose Error:{ex}"); } base.DoDispose(); } } }