初步版本251204
This commit is contained in:
@@ -3,6 +3,8 @@ using FATrace.HKNetLib.Hardware;
|
||||
using FATrace.HKNetLib.Wrapper;
|
||||
using FATrace.Model;
|
||||
using FATrace.OEMApp.Services;
|
||||
using FATrace.OEMApp.Model;
|
||||
using System.Threading.Tasks;
|
||||
using LibVLCSharp.Shared;
|
||||
using NLog;
|
||||
using ReaLTaiizor.Forms;
|
||||
@@ -51,8 +53,8 @@ namespace FATrace.OEMApp
|
||||
LvLog.GridLines = true;
|
||||
LvLog.HeaderStyle = ColumnHeaderStyle.Nonclickable;
|
||||
LvLog.Columns.Add("时间", 150);
|
||||
LvLog.Columns.Add("级别", 60);
|
||||
LvLog.Columns.Add("消息", 720);
|
||||
LvLog.Columns.Add("级别", 100);
|
||||
LvLog.Columns.Add("消息", 800);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -98,6 +100,7 @@ namespace FATrace.OEMApp
|
||||
/// </summary>
|
||||
private PLCDataService PLCDataService { get; set; }
|
||||
private TimeClearDataService TimeClearService { get; set; }
|
||||
private System.Windows.Forms.Timer _statusTimer;
|
||||
|
||||
/// <summary>
|
||||
/// 主窗体加载:
|
||||
@@ -143,8 +146,13 @@ namespace FATrace.OEMApp
|
||||
{
|
||||
DownloadTaskWorker.Instance.Start(HkCameraClient);
|
||||
LogInfo("下载队列服务已启动");
|
||||
JellyfinMonitorQueueService.Instance.Start();
|
||||
LogInfo("Jellyfin 监控服务已启动");
|
||||
try { DownloadTaskWorker.Instance.DownloadFileNameChanged += OnDownloadFileNameChanged; } catch { }
|
||||
try { DownloadTaskWorker.Instance.TaskStarted += OnTaskStatusChanged; } catch { }
|
||||
try { DownloadTaskWorker.Instance.TaskCompleted += OnTaskStatusChanged; } catch { }
|
||||
try { DownloadTaskWorker.Instance.TaskFailed += OnTaskFailed; } catch { }
|
||||
// JellyfinMonitorQueueService.Instance.Start();
|
||||
// LogInfo("Jellyfin 监控服务已启动");
|
||||
LogInfo("Jellyfin 监控服务已停用");
|
||||
TimeClearService = new TimeClearDataService();
|
||||
TimeClearService.Info += (m) => LogInfo($"[清理]{m}");
|
||||
TimeClearService.Start();
|
||||
@@ -158,9 +166,15 @@ namespace FATrace.OEMApp
|
||||
|
||||
// 初始化 gridRULog 并启动 UI 定时刷新
|
||||
InitRuLogGrid();
|
||||
// 立即刷新一次,避免首次 1s 空白
|
||||
// 仅初始化一次,当天数据
|
||||
RefreshRuLogGrid();
|
||||
StartTaskUiTimer();
|
||||
|
||||
// 初始化底部连接状态(立即检测一次 + 定时轻量检测)
|
||||
SafeSetStatus(tslPlcConnection, PLCDataService?.PlcConnected == true, "Plc连接状态");
|
||||
_ = UpdateDbStatusAsync();
|
||||
_ = UpdateNasStatusAsync();
|
||||
_ = UpdateNvrStatusAsync();
|
||||
StartStatusTimer();
|
||||
|
||||
//materialListView1.DataBindings
|
||||
try
|
||||
@@ -194,17 +208,30 @@ namespace FATrace.OEMApp
|
||||
/// <param name="Code"></param>
|
||||
private void PLCDataService_ScanCodeEventHandler(object? sender, string Code)
|
||||
{
|
||||
//解析Code条码数据,内包条码数据
|
||||
CurParsedCodeInfo = NVRCom.ParseCodeFull(Code);
|
||||
|
||||
var taskId = DownloadTaskWorker.Instance.Enqueue(
|
||||
CurParsedCodeInfo,
|
||||
user: CurUserName,
|
||||
start: DateTime.Now,
|
||||
end: DateTime.Now.AddSeconds(DownloadTaskWorker.VideoTime+2)
|
||||
);
|
||||
//MessageBox.Show($"[Test] 已入队下载任务,Id={taskId}");
|
||||
|
||||
LogInfo($"扫码: {Code}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// PLC数据服务:PLC连接
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
/// <summary>
|
||||
/// PLC数据服务:PLC连接
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void PLCDataService_PlcConnectedEventHandler(object? sender, string e)
|
||||
{
|
||||
LogInfo($"PLC连接: {e}");
|
||||
var ok = string.Equals(e, "OK", StringComparison.OrdinalIgnoreCase);
|
||||
SafeSetStatus(tslPlcConnection, ok, "Plc连接状态");
|
||||
}
|
||||
|
||||
private void NVRLogin()
|
||||
@@ -220,10 +247,12 @@ namespace FATrace.OEMApp
|
||||
{
|
||||
MessageBox.Show("登录成功");
|
||||
LogInfo("NVR 登录成功");
|
||||
_ = UpdateNvrStatusAsync();
|
||||
return;
|
||||
}
|
||||
MessageBox.Show($"登录失败:{HkCameraClient.LastMsgErr}");
|
||||
LogError($"NVR 登录失败: {HkCameraClient.LastMsgErr}");
|
||||
SafeSetStatus(tslNVRConnection, false, "NVR连接状态");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -250,15 +279,24 @@ namespace FATrace.OEMApp
|
||||
|
||||
#region 内包信息
|
||||
|
||||
/// <summary>
|
||||
/// 内包条码
|
||||
/// </summary>
|
||||
public string CurInBagCode { get; set; } = "AAAAAA";
|
||||
///// <summary>
|
||||
///// 内包条码
|
||||
///// </summary>
|
||||
//public string CurInBagCode { get; set; } = "AAAAAA";
|
||||
|
||||
///// <summary>
|
||||
///// 内包条码 原料名称
|
||||
///// </summary>
|
||||
//public string CurRawName { get; set; } = "添加剂Test";
|
||||
///// <summary>
|
||||
///// 内包条码 原料代码
|
||||
///// </summary>
|
||||
//public string CurRawCode { get; set; } = "ASASASS";
|
||||
|
||||
/// <summary>
|
||||
/// 内包条码 原料名称
|
||||
/// 内包条码 解析结果
|
||||
/// </summary>
|
||||
public string CurInBagRawName { get; set; } = "添加剂Test";
|
||||
public ParsedCodeInfo CurParsedCodeInfo { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -282,25 +320,6 @@ namespace FATrace.OEMApp
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 下载按钮:仅将请求入队为 DownloadTask,由后台 DownloadTaskWorker 顺序处理。
|
||||
/// 注意:不会在此处直接调用 SDK 下载,也不会订阅 SDK 事件,避免并发与重复。
|
||||
/// </summary>
|
||||
private void btnLoadVideo_Click(object sender, EventArgs e)
|
||||
{
|
||||
// 仅入队下载任务,由后台 DownloadTaskWorker 顺序处理
|
||||
var taskId = DownloadTaskWorker.Instance.Enqueue(
|
||||
code: CurInBagCode,
|
||||
rawName: CurInBagRawName,
|
||||
user: CurUserName,
|
||||
start: DateTime.Now.AddSeconds(-30),
|
||||
end: DateTime.Now
|
||||
);
|
||||
MessageBox.Show($"已入队下载任务,Id={taskId}");
|
||||
LogInfo($"下载任务入队 Id={taskId} Code={CurInBagCode}");
|
||||
}
|
||||
|
||||
private void HkCameraClient_NVRLoadVideoProcessEventHandler(object? sender, short value)
|
||||
{
|
||||
this.BeginInvoke(new Action(() =>
|
||||
@@ -310,7 +329,7 @@ namespace FATrace.OEMApp
|
||||
if (value >= 100 && _lastProgressLogged != 100)
|
||||
{
|
||||
_lastProgressLogged = 100;
|
||||
LogInfo("下载进度 100%");
|
||||
LogInfo($"{DownloadTaskWorker.Instance.CurDownloadTask.Code} - 下载进度 100%");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -592,13 +611,12 @@ namespace FATrace.OEMApp
|
||||
private void btnTestAction_Click(object sender, EventArgs e)
|
||||
{
|
||||
var taskId = DownloadTaskWorker.Instance.Enqueue(
|
||||
code: CurInBagCode,
|
||||
rawName: CurInBagRawName,
|
||||
CurParsedCodeInfo,
|
||||
user: CurUserName,
|
||||
start: DateTime.Now.AddSeconds(-100),
|
||||
end: DateTime.Now
|
||||
start: DateTime.Now,
|
||||
end: DateTime.Now.AddSeconds(DownloadTaskWorker.VideoTime)
|
||||
);
|
||||
MessageBox.Show($"[Test] 已入队下载任务,Id={taskId}");
|
||||
//MessageBox.Show($"[Test] 已入队下载任务,Id={taskId}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -628,59 +646,12 @@ namespace FATrace.OEMApp
|
||||
}
|
||||
|
||||
LogInfo($"下载完成: {localNameOrPath}");
|
||||
|
||||
// 先保存当前的信息,记录主键 Id
|
||||
var rawUse = new OEMRawUse()
|
||||
{
|
||||
InBagCode = CurInBagCode,
|
||||
RawName = CurInBagRawName,
|
||||
User = CurUserName,
|
||||
UrlState = false,
|
||||
VideoUrl = string.Empty
|
||||
};
|
||||
long rawUseId = 0;
|
||||
try
|
||||
{
|
||||
rawUseId = FSqlContext.FDb.Insert<OEMRawUse>(rawUse).ExecuteIdentity();
|
||||
_downloadProcessingKeys[key] = rawUseId;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_downloadProcessingKeys.TryRemove(key, out _);
|
||||
System.Diagnostics.Debug.WriteLine($"[NVRLoadVideoComplete] 插入 OEMRawUse 失败: {ex.Message}");
|
||||
return;
|
||||
}
|
||||
|
||||
// 后台执行,避免阻塞 UI 线程
|
||||
Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var monitor = new JellyfinMonitorService();
|
||||
await monitor.MonitorAndUpdateAfterDownloadAsync(
|
||||
oemRawUseId: rawUseId,
|
||||
videoLocalPathOrName: localNameOrPath,
|
||||
code: CurInBagCode,
|
||||
rawName: CurInBagRawName,
|
||||
userName: CurUserName,
|
||||
cancellationToken: CancellationToken.None
|
||||
).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex1)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"[JellyfinMonitor] 异常: {ex1.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
// 移除去重 key,允许后续相同文件再次处理(如需重试)
|
||||
_downloadProcessingKeys.TryRemove(key, out _);
|
||||
}
|
||||
});
|
||||
// Jellyfin 监控已停用:仅移除去重 key
|
||||
_downloadProcessingKeys.TryRemove(key, out _);
|
||||
}
|
||||
|
||||
#region 任务监控(gridRULog / DataGridView)
|
||||
|
||||
private System.Windows.Forms.Timer _taskUiTimer;
|
||||
private BindingSource ruLogBindingSource;
|
||||
private BindingList<RuLogRow> ruLogBindingList;
|
||||
|
||||
@@ -691,6 +662,7 @@ namespace FATrace.OEMApp
|
||||
{
|
||||
public string TimeText { get; set; } = string.Empty;
|
||||
public string Type { get; set; } = string.Empty; // 下载/监听
|
||||
public string Code { get; set; } = string.Empty;
|
||||
public long TaskId { get; set; }
|
||||
public string StatusText { get; set; } = string.Empty;
|
||||
public string? ProgressText { get; set; }
|
||||
@@ -726,6 +698,14 @@ namespace FATrace.OEMApp
|
||||
AutoSizeMode = DataGridViewAutoSizeColumnMode.None
|
||||
});
|
||||
gridRULog.Columns.Add(new DataGridViewTextBoxColumn
|
||||
{
|
||||
Name = "colCode",
|
||||
HeaderText = "条码",
|
||||
DataPropertyName = nameof(RuLogRow.Code),
|
||||
Width = 400,
|
||||
AutoSizeMode = DataGridViewAutoSizeColumnMode.None
|
||||
});
|
||||
gridRULog.Columns.Add(new DataGridViewTextBoxColumn
|
||||
{
|
||||
Name = "colTaskId",
|
||||
HeaderText = "任务Id",
|
||||
@@ -772,7 +752,6 @@ namespace FATrace.OEMApp
|
||||
gridRULog.ColumnHeadersDefaultCellStyle.ForeColor = Color.Black;
|
||||
gridRULog.RowHeadersVisible = false;
|
||||
// 使用 Designer 中的 Location/Size 与 Anchor,不额外 Dock
|
||||
gridRULog.BringToFront();
|
||||
|
||||
// 跟随父容器尺寸变化进行定位与大小调整
|
||||
materialCard2.Resize -= MaterialCard2_Resize;
|
||||
@@ -810,7 +789,6 @@ namespace FATrace.OEMApp
|
||||
var height = Math.Max(120, client.Height - top - 9);
|
||||
gridRULog.Location = new Point(left, top);
|
||||
gridRULog.Size = new Size(width, height);
|
||||
gridRULog.BringToFront();
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
@@ -820,40 +798,22 @@ namespace FATrace.OEMApp
|
||||
LayoutRuLogGrid();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 启动 UI 定时器,定时刷新下载与 Jellyfin 监听任务状态
|
||||
/// </summary>
|
||||
private void StartTaskUiTimer()
|
||||
{
|
||||
_taskUiTimer = new System.Windows.Forms.Timer();
|
||||
_taskUiTimer.Interval = 1000; // 1s 刷新
|
||||
_taskUiTimer.Tick += TaskUiTimer_Tick;
|
||||
_taskUiTimer.Start();
|
||||
}
|
||||
|
||||
private void TaskUiTimer_Tick(object? sender, EventArgs e)
|
||||
{
|
||||
RefreshRuLogGrid();
|
||||
}
|
||||
// 定时刷新已移除:仅在下载开始/完成/失败时按需更新
|
||||
|
||||
/// <summary>
|
||||
/// 刷新 gridRULog(下载 + 监听)
|
||||
/// 刷新 gridRULog(仅当天下载)
|
||||
/// </summary>
|
||||
private void RefreshRuLogGrid()
|
||||
{
|
||||
try
|
||||
{
|
||||
var db = FSqlContext.FDb;
|
||||
var today = DateTime.Today;
|
||||
var downloads = db.Select<DownloadTask>()
|
||||
.Where(a => a.UpdateTime >= today)
|
||||
.OrderByDescending(a => a.UpdateTime)
|
||||
.Limit(50)
|
||||
.ToList();
|
||||
var monitors = db.Select<JellyfinMonitorTask>()
|
||||
.OrderByDescending(a => a.UpdateTime)
|
||||
.Limit(50)
|
||||
.ToList();
|
||||
|
||||
var rows = new List<RuLogRow>(downloads.Count + monitors.Count);
|
||||
var rows = new List<RuLogRow>(downloads.Count);
|
||||
|
||||
// 运行中优先
|
||||
foreach (var t in downloads.Where(x => x.Status == TaskStatus.Running))
|
||||
@@ -862,24 +822,14 @@ namespace FATrace.OEMApp
|
||||
{
|
||||
TimeText = t.UpdateTime.ToString("HH:mm:ss"),
|
||||
Type = "下载",
|
||||
Code = t.Code ?? string.Empty,
|
||||
TaskId = t.Id,
|
||||
StatusText = t.Status.ToString(),
|
||||
ProgressText = t.Progress.ToString(),
|
||||
Remark = string.IsNullOrWhiteSpace(t.Error) ? (t.VideoFilePath ?? string.Empty) : t.Error!
|
||||
});
|
||||
}
|
||||
foreach (var t in monitors.Where(x => x.Status == TaskStatus.Running))
|
||||
{
|
||||
rows.Add(new RuLogRow
|
||||
{
|
||||
TimeText = t.UpdateTime.ToString("HH:mm:ss"),
|
||||
Type = "监听",
|
||||
TaskId = t.Id,
|
||||
StatusText = t.Status.ToString(),
|
||||
ProgressText = string.Empty,
|
||||
Remark = string.IsNullOrWhiteSpace(t.Error) ? (t.FoundItemId ?? t.LocalFileNameOrPath ?? string.Empty) : t.Error!
|
||||
});
|
||||
}
|
||||
// 监听任务展示已移除
|
||||
|
||||
// 其余
|
||||
foreach (var t in downloads.Where(x => x.Status != TaskStatus.Running))
|
||||
@@ -888,26 +838,16 @@ namespace FATrace.OEMApp
|
||||
{
|
||||
TimeText = t.UpdateTime.ToString("HH:mm:ss"),
|
||||
Type = "下载",
|
||||
Code = t.Code ?? string.Empty,
|
||||
TaskId = t.Id,
|
||||
StatusText = t.Status.ToString(),
|
||||
ProgressText = t.Progress.ToString(),
|
||||
Remark = string.IsNullOrWhiteSpace(t.Error) ? (t.VideoFilePath ?? string.Empty) : t.Error!
|
||||
});
|
||||
}
|
||||
foreach (var t in monitors.Where(x => x.Status != TaskStatus.Running))
|
||||
{
|
||||
rows.Add(new RuLogRow
|
||||
{
|
||||
TimeText = t.UpdateTime.ToString("HH:mm:ss"),
|
||||
Type = "监听",
|
||||
TaskId = t.Id,
|
||||
StatusText = t.Status.ToString(),
|
||||
ProgressText = string.Empty,
|
||||
Remark = string.IsNullOrWhiteSpace(t.Error) ? (t.FoundItemId ?? t.LocalFileNameOrPath ?? string.Empty) : t.Error!
|
||||
});
|
||||
}
|
||||
// 监听任务展示已移除
|
||||
|
||||
// 批量更新绑定列表,尽量减少闪烁
|
||||
// 批量更新绑定列表
|
||||
ruLogBindingList.RaiseListChangedEvents = false;
|
||||
ruLogBindingList.Clear();
|
||||
foreach (var r in rows)
|
||||
@@ -923,6 +863,138 @@ namespace FATrace.OEMApp
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTaskStatusChanged(DownloadTask t)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (t.UpdateTime.Date != DateTime.Today) return;
|
||||
if (InvokeRequired)
|
||||
{
|
||||
BeginInvoke(new Action(() => UpsertRuLogRowFromTask(t)));
|
||||
}
|
||||
else
|
||||
{
|
||||
UpsertRuLogRowFromTask(t);
|
||||
}
|
||||
|
||||
if (t.Status == TaskStatus.Completed || t.Status == TaskStatus.Failed)
|
||||
{
|
||||
ResetProgressBar();
|
||||
}
|
||||
if (t.Status == TaskStatus.Completed)
|
||||
{
|
||||
_ = SaveCsvForTaskAsync(t);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
private void OnTaskFailed(DownloadTask t, string? error)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (t.UpdateTime.Date != DateTime.Today) return; // 仅当天
|
||||
if (InvokeRequired)
|
||||
{
|
||||
BeginInvoke(new Action(() => UpsertRuLogRowFromTask(t)));
|
||||
}
|
||||
else
|
||||
{
|
||||
UpsertRuLogRowFromTask(t);
|
||||
}
|
||||
// 失败同样清零进度
|
||||
ResetProgressBar();
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
private void UpsertRuLogRowFromTask(DownloadTask t)
|
||||
{
|
||||
if (ruLogBindingList == null) return;
|
||||
var existing = ruLogBindingList.FirstOrDefault(x => x.TaskId == t.Id);
|
||||
if (existing == null)
|
||||
{
|
||||
ruLogBindingList.Insert(0, new RuLogRow
|
||||
{
|
||||
TimeText = t.UpdateTime.ToString("HH:mm:ss"),
|
||||
Type = "下载",
|
||||
Code = t.Code ?? string.Empty,
|
||||
TaskId = t.Id,
|
||||
StatusText = t.Status.ToString(),
|
||||
ProgressText = t.Progress.ToString(),
|
||||
Remark = string.IsNullOrWhiteSpace(t.Error) ? (t.VideoFilePath ?? string.Empty) : t.Error!
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
existing.TimeText = t.UpdateTime.ToString("HH:mm:ss");
|
||||
existing.StatusText = t.Status.ToString();
|
||||
existing.ProgressText = t.Progress.ToString();
|
||||
existing.Code = t.Code ?? string.Empty;
|
||||
existing.Remark = string.IsNullOrWhiteSpace(t.Error) ? (t.VideoFilePath ?? string.Empty) : t.Error!;
|
||||
}
|
||||
ruLogBindingList.ResetBindings();
|
||||
}
|
||||
|
||||
private void ResetProgressBar()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (DownloadProgressBarMain == null || DownloadProgressBarMain.IsDisposed) return;
|
||||
if (InvokeRequired)
|
||||
{
|
||||
BeginInvoke(new Action(() => DownloadProgressBarMain.Value = 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
DownloadProgressBarMain.Value = 0;
|
||||
}
|
||||
_lastProgressLogged = -1;
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
private async Task SaveCsvForTaskAsync(DownloadTask t)
|
||||
{
|
||||
try
|
||||
{
|
||||
var dto = new RawUseCsvDto
|
||||
{
|
||||
RawCode = t.RawCode,
|
||||
RawName = t.RawName,
|
||||
InBagCode = t.Code,
|
||||
OpUser = t.User,
|
||||
VideoSavePath = t.VideoFilePath,
|
||||
UseTime = t.UpdateTime
|
||||
};
|
||||
var svc = new CsvService();
|
||||
var path = await Task.Run(() => svc.ExportSingle(dto));
|
||||
SafeSetCsvState($"CSV保存成功: {path}", true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SafeSetCsvState($"CSV保存失败: {ex.Message}", false);
|
||||
}
|
||||
}
|
||||
|
||||
private void SafeSetCsvState(string text, bool ok)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (txtCsvSaveState == null || txtCsvSaveState.IsDisposed) return;
|
||||
if (InvokeRequired)
|
||||
{
|
||||
BeginInvoke(new Action(() => { txtCsvSaveState.Text = text ?? string.Empty; txtCsvSaveState.ForeColor = ok ? Color.ForestGreen : Color.DarkRed; }));
|
||||
}
|
||||
else
|
||||
{
|
||||
txtCsvSaveState.Text = text ?? string.Empty;
|
||||
txtCsvSaveState.ForeColor = ok ? Color.ForestGreen : Color.DarkRed;
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
private static void SetDataGridViewDoubleBuffered(DataGridView dgv)
|
||||
{
|
||||
try
|
||||
@@ -947,8 +1019,112 @@ namespace FATrace.OEMApp
|
||||
|
||||
protected override void OnFormClosing(FormClosingEventArgs e)
|
||||
{
|
||||
try { DownloadTaskWorker.Instance.DownloadFileNameChanged -= OnDownloadFileNameChanged; } catch { }
|
||||
try { DownloadTaskWorker.Instance.TaskStarted -= OnTaskStatusChanged; } catch { }
|
||||
try { DownloadTaskWorker.Instance.TaskCompleted -= OnTaskStatusChanged; } catch { }
|
||||
try { DownloadTaskWorker.Instance.TaskFailed -= OnTaskFailed; } catch { }
|
||||
try { _statusTimer?.Stop(); _statusTimer?.Dispose(); _statusTimer = null; } catch { }
|
||||
try { TimeClearService?.Stop(); } catch { }
|
||||
base.OnFormClosing(e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当前下载文件的名称改变
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
private void OnDownloadFileNameChanged(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (DownloadFileName == null || DownloadFileName.IsDisposed) return;
|
||||
if (InvokeRequired)
|
||||
{
|
||||
try { BeginInvoke(new Action(() => DownloadFileName.Text = name ?? string.Empty)); } catch { }
|
||||
}
|
||||
else
|
||||
{
|
||||
try { BeginInvoke(new Action(() => DownloadFileName.Text = name ?? string.Empty)); } catch { }
|
||||
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
#region 底部状态栏(PLC/DB/NAS/NVR)
|
||||
private void StartStatusTimer()
|
||||
{
|
||||
try
|
||||
{
|
||||
_statusTimer = new System.Windows.Forms.Timer();
|
||||
_statusTimer.Interval = 30000; // 30s 轻量检测
|
||||
_statusTimer.Tick += async (s, e) =>
|
||||
{
|
||||
await UpdateDbStatusAsync();
|
||||
await UpdateNasStatusAsync();
|
||||
await UpdateNvrStatusAsync();
|
||||
};
|
||||
_statusTimer.Start();
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
private void SafeSetStatus(ToolStripStatusLabel lbl, bool ok, string title)
|
||||
{
|
||||
try
|
||||
{
|
||||
string text = ok ? $"{title}: 正常" : $"{title}: 异常";
|
||||
var fore = ok ? Color.ForestGreen : Color.DarkRed;
|
||||
if (InvokeRequired)
|
||||
{
|
||||
BeginInvoke(new Action(() => { lbl.Text = text; lbl.ForeColor = fore; }));
|
||||
}
|
||||
else
|
||||
{
|
||||
lbl.Text = text; lbl.ForeColor = fore;
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
private async Task UpdateDbStatusAsync()
|
||||
{
|
||||
bool ok = false;
|
||||
try
|
||||
{
|
||||
var db = FSqlContext.FDb;
|
||||
var ret = await db.Ado.ExecuteScalarAsync("SELECT 1");
|
||||
ok = Convert.ToString(ret) == "1";
|
||||
}
|
||||
catch { ok = false; }
|
||||
SafeSetStatus(tslSqlConnection, ok, "服务连接状态");
|
||||
}
|
||||
|
||||
private async Task UpdateNasStatusAsync()
|
||||
{
|
||||
bool ok = false;
|
||||
try
|
||||
{
|
||||
var path = HkCameraClient?.NVRVideoSavePath;
|
||||
if (!string.IsNullOrWhiteSpace(path))
|
||||
{
|
||||
ok = await Task.Run(() => System.IO.Directory.Exists(path));
|
||||
}
|
||||
}
|
||||
catch { ok = false; }
|
||||
SafeSetStatus(tslNasConnection, ok, "NAS连接状态");
|
||||
}
|
||||
|
||||
private async Task UpdateNvrStatusAsync()
|
||||
{
|
||||
bool ok = false;
|
||||
try
|
||||
{
|
||||
ok = HkCameraClient != null && HkCameraClient.NVRLoginState && HkCameraClient.IsOnline();
|
||||
}
|
||||
catch { ok = false; }
|
||||
await Task.Yield();
|
||||
SafeSetStatus(tslNVRConnection, ok, "NVR连接状态");
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user