aspnet核心停止后台运行任务

时间:2018-06-01 19:36:52

标签: c# asp.net-web-api asp.net-core signalr task

我有一个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);
            }
        });
    }
}

这是按预期工作的。但我想知道这是一个好方法还是还有其他更好的选择。

如果我使用负载均衡器和多个应用程序实例,这也行不通。我该如何解决这个问题。

0 个答案:

没有答案