ядро aspnet остановить фоновое выполнение задачи - PullRequest
0 голосов
/ 01 июня 2018

У меня есть метод API, который работает в фоновом режиме (асинхронный) в течение ~ 6 минут.Я хочу разрешить пользователю отменить его из другого запроса API.

Например,

/api/credits/post/25 запустит фоновую задачу и немедленно возвратит ответ OK.

/api/credits/stop/25 прекратит запуск фоновой задачи.

мой текущий код.

API

[Route("api/[controller]")]
public class CreditController : Controller
{
    private readonly CreditService _creditService;
    public CreditController (CreditService creditService)
    {
        _creditService = creditService;
    }

    [HttpPost("[action]")]
    public string Post(int id)
    {
        if (_creditService.Instances.Any(p => p.ID == id))
            return "already running " + id;
        _creditService.Post(id, (s,e) =>
        {
            // sending realtime changes to user using SignalR.
            // so that they will see progress and whats running in background 
        });
        return "started " + id;
    }

    [HttpPost("[action]")]
    public string Stop(int id)
    {
        var instance = _creditService.Instances.SingleOrDefault(p => p.ID == id));
        if (instance == null)
            return id + " is not running";
        instance.CancelToken.Cancel();
        return id + " stoppped";            
    }
}

Служба

public class CreditService
{
    public static List<CreditService> Instances = new List<CreditService>();

    public Status<object> Status = new Status<object>();
    public CancellationTokenSource CancelToken = new CancellationTokenSource();

    public Task Post(int id, PropertyChangedEventHandler handler = null)
    {
        Instances.Add(this);
        if (handler != null) Status.PropertyChanged += handler;

        return Task.Factory.StartNew(() =>
        {
            try
            {
                // long running task
            }
            catch (Exception e)
            {
                Status.Error = e.Message ?? e.ToString();
            }
            finally
            {
                if (handler != null) Status.PropertyChanged -= handler;
                Status.Clear();
                CancelToken.Dispose();
                Instances.Remove(this);
            }
        });
    }
}

Это работает, как и ожидалось.но я хочу знать, является ли это хорошим подходом или есть другая лучшая альтернатива этому.

Также это не будет работать, если я использую балансировщик нагрузки и несколько экземпляров приложения.Как мне это исправить.

...