Планировщик на ASP.NET 6 с помощью Quartz.NET и мониторинга SignalR
В этой статье мы собираемся использовать Quartz.NET для планирования наших заданий и использовать Signalr для просмотра мониторинга результатов/прогресса.
Создайте js-файл SignalR.
создайте файл hub.js и сохраните его в папке wwwroot->js.
const connection = new signalR.HubConnectionBuilder().withUrl("/hub").build();
async function start() {
try {
await connection.start();
console.log("SignalR Connected.");
} catch (err) {
console.log(err);
setTimeout(start, 5000);
}
};
connection.onclose(async () => {
await start();
});
start();
connection.on("ConcurrentJobs", function (message) {
var li = document.createElement("li");
document.getElementById("concurrentJobs").appendChild(li);
li.textContent = `${message}`;
});
connection.on("NonConcurrentJobs", function (message) {
var li = document.createElement("li");
document.getElementById("nonConcurrentJobs").appendChild(li);
li.textContent = `${message}`;
});
HTML для отображения сообщения
В Index.cshtml добавьте приведенный ниже код для отображения сообщения от SignalR.
<div class="container">
<div class="row">
<div class="col-6">
<ul id="concurrentJobs"></ul>
</div>
<div class="col-6">
<ul id="nonConcurrentJobs"></ul>
</div>
</div>
</div>
<script src="~/microsoft/Signalr/dist/browser/signalr.js"></script>
<script src=~/js/hub.js></script>
Центр вакансий
Создайте имя файла класса CS JobsHub и замените приведенным ниже кодом.
public class JobsHub : Hub
{
//message used for concurrent job message
public Task SendConcurrentJobsMessage(string message)
{
return Clients.All.SendAsync("ConcurrentJobs", message);
}
//message used for nonconcurrent job message
public Task SendNonConcurrentJobsMessage(string message)
{
return Clients.All.SendAsync("NonConcurrentJobs", message);
}
}
Создавайте рабочие места
- Параллельная работа
Создайте файл класса cs с именем ConconcurrentJob и замените приведенным ниже кодом.
public class ConconcurrentJob : IJob
{
private static int _counter = 0;
private readonly IHubContext<JobsHub> _hubContext;
public ConconcurrentJob(IHubContext<JobsHub> hubContext)
{
_hubContext = hubContext;
}
public async Task Execute(IJobExecutionContext context)
{
var count = _counter++;
//start the job
var beginMessage = $"Conconcurrent Job BEGIN {count} {DateTime.UtcNow}";
await _hubContext.Clients.All.SendAsync("ConcurrentJobs", beginMessage);
//we have long running job
Thread.Sleep(5000);
//complete the job
var endMessage = $"Conconcurrent Job END {count} {DateTime.UtcNow}";
await _hubContext.Clients.All.SendAsync("ConcurrentJobs", endMessage);
}
}
Создайте файл класса cs с именем NonConconcurrentJob и замените приведенным ниже кодом.
public class ConconcurrentJob : IJob
{
private static int _counter = 0;
private readonly IHubContext<JobsHub> _hubContext;
public ConconcurrentJob(IHubContext<JobsHub> hubContext)
{
_hubContext = hubContext;
}
public async Task Execute(IJobExecutionContext context)
{
var count = _counter++;
//start the job
var beginMessage = $"Conconcurrent Job BEGIN {count} {DateTime.UtcNow}";
await _hubContext.Clients.All.SendAsync("nonConcurrentJobs", beginMessage);
//we have long running job
Thread.Sleep(5000);
//complete the job
var endMessage = $"Conconcurrent Job END {count} {DateTime.UtcNow}";
await _hubContext.Clients.All.SendAsync("nonConcurrentJobs", endMessage);
}
}
Program.cs
Добавьте приведенный ниже код в Program.cs
builder.Services.AddQuartz(q =>
{
q.UseMicrosoftDependencyInjectionJobFactory();
var conconcurrentJobKey = new JobKey("ConconcurrentJob");
q.AddJob<ConconcurrentJob>(opts => opts.WithIdentity(conconcurrentJobKey));
q.AddTrigger(opts => opts
.ForJob(conconcurrentJobKey)
.WithIdentity("ConconcurrentJob-trigger")
.WithSimpleSchedule(x => x
.WithIntervalInSeconds(5)
.RepeatForever()));
var nonConconcurrentJobKey = new JobKey("NonConconcurrentJob");
q.AddJob<NonConconcurrentJob>(opts => opts.WithIdentity(nonConconcurrentJobKey));
q.AddTrigger(opts => opts
.ForJob(nonConconcurrentJobKey)
.WithIdentity("NonConconcurrentJob-trigger")
.WithSimpleSchedule(x => x
.WithIntervalInSeconds(5)
.RepeatForever()));
});
builder.Services.AddQuartzHostedService(
q => q.WaitForJobsToComplete = true);
builder.Services.AddSignalR();
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<JobsHub>("/hub");
});
Только полноправные пользователи могут оставлять комментарии. Аутентифицируйтесь пожалуйста, используя сервисы.