Вызов сервиса из контроллера
Есть контроллер , Action метод которого должен создавать задачу(их может быть много разных), и возвращать, сообщение, что либо задачу успешно создана, либо эта задача уже в работе запустить можно только 1 экземпляр 1 вида задачи задачи.
[HttpPost]
public async Task<ActionResult> CreateTask([FromBody] CreateTaskDto createTaskDto)
{
var command = new CreateTaskCommand()
{
Name = createTaskDto.Type.GetDisplayName(),
Path = createTaskDto.Path,
Type = createTaskDto.Type
};
var getExemplarTask = TaskCommander.Add(command.Type);
if (getExemplarTask != null)
{
var vm = await Mediator.Send(command);
getExemplarTask.Id = vm.Id;
getExemplarTask?.Service.StartAsync(getExemplarTask.CancellationTokenSource.Token);
return Ok(new AppResponse(message: $"Task {createTaskDto.Type.GetDisplayName()} succesfully created!", data: vm));
}
return Ok(new AppResponse(message: $"Task {createTaskDto.Type.GetDisplayName()} succesfully created!"));
}
в поле Type enum`ka с задачами
Так же есть второй Action метод, для прерывания задачи по Id задачи
[HttpGet("{Id}")]
public async Task<ActionResult> CancelTask(int Id)
{
var command = new UpdateTaskCommand()
{
Id = Id,
Status = Status.Canceled,
FinishDate = DateTime.Now
};
TaskCommander.Cancel(Id);
var vm = await Mediator.Send(command);
return Ok(new AppResponse(message: $"Task {vm.Type.GetDisplayName()} succesfully canceled!", data: vm));
}
Пробовал создавать отдельный класс TaskController , в нем методы Add и Cancel и словарь типа IService | CancelationTokenSource (IService - интефейс реализуемый во всех сервисах).
При добавлении проверяем есть ли данная задача(по имени) в словаре, Если нет, то добавляем задачу, Через Task.Run(* , CancelationTokenSource.Token) запускаем и говорим медиатору ,чтобы сохранил в БД результат.
При удалении ищем в словаре так же по имени запущенный сервис, если он есть, то берем у него значение (CancelationTokenSource) и используем _cts.Cancel()
Однако эта конструкция работать оказалось. Столкнулся со следующими проблемами:
- Из-за Task.Run сохранение в БД происходит очень медленно
- Отмена задачи не происходит совсем
Вопрос: Как правильно реализовать создание и отмену задачи, а так же проверку на уникальность созданной задачи?
UPD:
Сам класс бизнес логики
public class CryptoFinderService : IService
{
public CryptoFinderService()
{
}
public async Task StartAsync(CancellationToken token)
{
/// Просто иммитация работы
while (true)
{
Debug.WriteLine("!!!!!");
await Task.Delay(1);
}
}
}
класс для добавления и удаления задач
public static class TaskCommander
{
private static List<ExemplarTask> _stackService = new();
public static ExemplarTask? Add(TaskType type)
{
var service = SelectTask(type);
var exemplar = new ExemplarTask()
{
Id = 0,
Name = type.GetDisplayName(),
Service = service,
CancellationTokenSource = new CancellationTokenSource()
};
var taskIsContains = _stackService
.Select(x => x.Name)
.Any(x => x == exemplar.Name);
if (taskIsContains)
{
return null;
}
_stackService.Add(exemplar);
return exemplar;
}
public static void Cancel(int Id)
{
var exemplar = _stackService
.FirstOrDefault(x => x.Id == Id);
exemplar?.CancellationTokenSource.Cancel();
}
public static IService SelectTask(TaskType type)
{
switch (type)
{
case TaskType.CryptoFinder:
return new CryptoFinderService();
default:
throw new TaskNotFound(nameof(TaskType));
}
}
public class ExemplarTask
{
public int Id { get; set; }
public string Name { get; set; }
public IService Service { get; set; }
public CancellationTokenSource CancellationTokenSource { get; set; }
}
}
По моей логике класс TaskCommander должен руководить созданными задачами. Запускать и прерывать работу задач, но работать оно увы и ах не хочет