我有一个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);
}
});
}
}
这是按预期工作的。但我想知道这是一个好方法还是还有其他更好的选择。
如果我使用负载均衡器和多个应用程序实例,这也行不通。我该如何解决这个问题。