.net-core - 如何在 Worker Service 中调度并行任务?
问题描述
我每 2 秒从具有 ModBus TCP 协议的生产机器上的 PLC 获得即时状态(停止、工作、关闭)。我正在使用 SignalR 协议向客户端发送即时状态。我将其定义为 Worker Service 以将其作为 Windows 服务运行。
我的问题是我想在每天 7:30 将每台机器的状态保存在数据库中。我该如何处理这种情况?
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Hosting;
using PLCMonitor.Models;
using PLCMonitor.Hubs;
using EasyModbus;
using System.Diagnostics;
using Microsoft.EntityFrameworkCore.SqlServer.Query.Internal;
namespace PLCMonitor.WorkerServices
{
public sealed class MessageBrokerPubSubWorker:BackgroundService
{
private readonly IHubContext<MessageBRokerHub> _messageBrokerHubContext;
public MessageBrokerPubSubWorker(IHubContext<MessageBRokerHub> messageBrokerHubContext)
{
_messageBrokerHubContext = messageBrokerHubContext;
}
protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
LineUptime BigSlitterUptime = new LineUptime
{
MachineId = 1,
MachineName = "Big Slitter",
IpAddress = "10.199.64.213",
PlcPort = Convert.ToInt32(502)
};
LineUptime SmallSlitterUptime = new LineUptime
{
MachineId = 2,
MachineName = "Small Slitter",
IpAddress = "10.199.64.214",
PlcPort = Convert.ToInt32(502)
};
LineUptime BigCoreCutUptime = new LineUptime
{
MachineId = 3,
MachineName = "Big Core Cut",
IpAddress = "10.199.64.211",
PlcPort = Convert.ToInt32(502)
};
LineUptime SmallCoreCutUptime = new LineUptime
{
MachineId = 4,
MachineName = "Small CoreCut",
IpAddress = "10.199.64.212",
PlcPort = Convert.ToInt32(502)
};
LineUptime Georg400Uptime = new LineUptime
{
MachineId = 6,
MachineName = "Georg 400",
IpAddress = "10.199.64.215",
PlcPort = Convert.ToInt32(502)
};
LineUptime Georg600Uptime = new LineUptime
{
MachineId = 7,
MachineName = "Georg 600",
IpAddress = "10.199.64.216",
PlcPort = Convert.ToInt32(502)
};
bool[] BigSlitterStatus = new bool[] { };
bool[] SmallSlitterStatus = new bool[] { };
bool[] BigCoreCutStatus = new bool[] { };
bool[] SmallCoreCutStatus = new bool[] { };
bool[] Georg400Status = new bool[] { };
bool[] Georg600Status = new bool[] { };
ModbusClient BigSlitter = new ModbusClient(BigSlitterUptime.IpAddress, BigSlitterUptime.PlcPort);
ModbusClient SmallSlitter = new ModbusClient(SmallSlitterUptime.IpAddress, SmallSlitterUptime.PlcPort);
ModbusClient BigCoreCut = new ModbusClient(BigCoreCutUptime.IpAddress, BigCoreCutUptime.PlcPort);
ModbusClient SmallCoreCut = new ModbusClient(SmallCoreCutUptime.IpAddress, SmallCoreCutUptime.PlcPort);
ModbusClient Georg400 = new ModbusClient(Georg400Uptime.IpAddress, Georg400Uptime.PlcPort);
ModbusClient Georg600 = new ModbusClient(Georg600Uptime.IpAddress, Georg600Uptime.PlcPort);
Stopwatch total = new Stopwatch();
List<Task> tasks = new List<Task>();
new Task(async () => await CheckMachineStatus(BigSlitterUptime, BigSlitter, BigSlitterStatus));
new Task(async () => await CheckMachineStatus(SmallSlitterUptime, SmallSlitter, SmallSlitterStatus)).Start();
new Task(async () => await CheckMachineStatus(BigCoreCutUptime, BigCoreCut, BigCoreCutStatus)).Start();
new Task(async () => await CheckMachineStatus(SmallCoreCutUptime, SmallCoreCut, SmallCoreCutStatus)).Start();
new Task(async () => await CheckMachineStatus(Georg400Uptime, Georg400, Georg400Status)).Start();
new Task(async () => await CheckMachineStatus(Georg600Uptime, Georg600, Georg600Status)).Start();
new Task(async () => await TotalTime(total)).Start();
async Task CheckMachineStatus(LineUptime machine, ModbusClient modbusClient, bool[] machineStatus)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
while (!stoppingToken.IsCancellationRequested)
{
DateTime startDate = DateTime.Now;
if (startDate.Hour == 7 && startDate.Minute == 29 && startDate.Second >=58)
{
bool bilgi = LineStatusDal.insertStatus(machine);
total.Restart();
stopwatch.Restart();
machine.ElapsedTime = TimeSpan.Zero;
machine.TotalDisconnected = TimeSpan.Zero;
machine.TotalRunned = TimeSpan.Zero;
machine.TotalStopped = TimeSpan.Zero;
}
else
{
try
{
modbusClient.Connect();
if (modbusClient.Connected)
{
machineStatus = modbusClient.ReadCoils(01280, 1);
machine.ElapsedTime = stopwatch.Elapsed;
modbusClient.Disconnect();
if (machineStatus[0] == true)
{
if (machine.Status != 2)
{
if (machine.Status == 1)
{
machine.TotalDisconnected += machine.ElapsedTime;
}
else
{
machine.TotalStopped += machine.ElapsedTime;
}
machine.Status = 2;
machine.StartDate = startDate;
stopwatch.Restart();
machine.ElapsedTime = stopwatch.Elapsed;
startDate = DateTime.Now;
}
await SendFromServerAsync(machine, stoppingToken);
}
else
{
if (machine.Status != 3)
{
if (machine.Status == 1)
{
machine.TotalDisconnected += machine.ElapsedTime;
}
else
{
machine.TotalRunned += machine.ElapsedTime;
}
machine.Status = 3;
machine.StartDate = startDate;
stopwatch.Restart();
machine.ElapsedTime = stopwatch.Elapsed;
startDate = DateTime.Now;
}
await SendFromServerAsync(machine, stoppingToken);
}
}
}
catch
{
machine.ElapsedTime = stopwatch.Elapsed;
/
if (machine.Status != 1)
{
if (machine.Status == 2)
{
machine.TotalRunned += machine.ElapsedTime;
}
else
{
machine.TotalStopped += machine.ElapsedTime;
}
machine.Status = 1;
machine.StartDate = startDate;
stopwatch.Restart();
machine.ElapsedTime = stopwatch.Elapsed;
startDate = DateTime.Now;
}
await SendFromServerAsync(machine, stoppingToken);
}
}
await Task.Delay(2000);
}
}
async Task TotalTime(Stopwatch total)
{
total.Start();
while (!stoppingToken.IsCancellationRequested)
{
await Task.Delay(2000);
DateTime today = DateTime.Now;
Console.WriteLine(($" Merhaba, saat şuan {total.Elapsed} {today}"));
await _messageBrokerHubContext.Clients.All.SendAsync("totaltime", total.Elapsed, today, stoppingToken);
}
}
async Task SendFromServerAsync(LineUptime machine, CancellationToken stoppingToken)
{
if (machine.MachineId == 1)
{
await _messageBrokerHubContext.Clients.All.SendAsync("bigslitter", machine, stoppingToken);
}else if (machine.MachineId == 2)
{
await _messageBrokerHubContext.Clients.All.SendAsync("smallslitter", machine, stoppingToken);
}
else if (machine.MachineId == 3)
{
await _messageBrokerHubContext.Clients.All.SendAsync("bigcorecut", machine, stoppingToken);
}
else if (machine.MachineId == 4)
{
await _messageBrokerHubContext.Clients.All.SendAsync("smallcorecut", machine, stoppingToken);
}
else if (machine.MachineId == 6)
{
await _messageBrokerHubContext.Clients.All.SendAsync("georg400", machine, stoppingToken);
}
else if (machine.MachineId == 7)
{
await _messageBrokerHubContext.Clients.All.SendAsync("georg600", machine, stoppingToken);
}
}
return Task.CompletedTask;
}
}
}
}
解决方案
推荐阅读
- vue.js - vue-cli 不创建文件夹结构
- php - 如何在 drupal 8 中通过 uri 加载图像?
- javascript - 当我使用 axios/vue js 发布到 php 时,Javascript .value 为空
- java - IBM Watson 语音到文本的依赖关系
- c# - 如何在剃刀中使模型更改为全局
- javafx - 透视滚动文本(选取器 iOS 样式)
- magento - XML 类别更新被忽略 + Manadev 过滤器问题 - Magento 1.9 Lesti FPC 1.4.8
- r - 为什么 Rcpp 仅在从 R 包调用时才起作用,而不是在直接通过 sourceCpp 获取时才起作用?
- ruby-on-rails - 在 Rails 中删除时发出警报
- javascript - 从 React.js 向 node.js API 发出多个请求