Я создаю приложение С#, используя Nancy API. У меня есть асинхронная операция, которая запускает очень длинный алгоритм оптимизации, который пользователь должен иногда отменять. Псевдокод выглядит следующим образом:
Get["/algorithm/run/", true] = async (parameters, ct) =>
{
var algy = new Algorithm();
var result = await Task.Run(() => algy.RunAlgorithm(ct), ct);
};
Как мне отменить CancellationToken
(ct) или создать новый метод отмены алгоритма?
Альтернатива, которую я пробовал, выглядит примерно так:
var cts = new CancellationTokenSource();
var cToken = cts.Token;
Get["/algorithm/run/", true] = async (parameters, ct) =>
{
var algy = new Algorithm();
var result = await Task.Run(() => algy.RunAlgorithm(cToken), cToken);
};
Get["/schedule/stop"] = _ =>
{
cts.Cancel();
};
Но это, очевидно, не работает, так как маршрут находится в своей собственной асинхронной задаче.
Я прочитал статью, размещенную здесь: http://blog.jonathanchannon.com/2013/08/24/async-route-handling-with-nancy/, в котором упоминается:
CancellationToken передается, поэтому вы можете проверить свойство ct.IsCancellationRequested, чтобы определить, хотите ли вы совместно отменить обработку в обработчике маршрута. Это свойство может быть установлено, например, в случае внутренней ошибки или промежуточного программного обеспечения, которое решает отменить запрос, или хост отключается. Если вы не знали, что Нэнси совместима с OWIN и совместима почти с тех пор, как вышла спецификация OWIN.
Любая помощь будет высоко оценена, поскольку я новичок в обработке потоков.
Полный пример:
using Nancy;
using Nancy.Hosting.Self;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace NancyApp
{
class Program
{
private static NancyHost NancyHost { get; set; }
private static HttpClient Client { get; set; }
static void Main(string[] args)
{
var configuration = new HostConfiguration()
{
UrlReservations = new UrlReservations() { CreateAutomatically = true }
};
NancyHost = new NancyHost(configuration, new Uri("http://localhost:1234"));
NancyHost.Start();
Client = new HttpClient();
Client.Timeout = new TimeSpan(1, 0, 0);
Client.BaseAddress = new Uri("http://localhost:1234");
Console.WriteLine("Hosting...\n");
Client.GetAsync("http://localhost:1234/run");
System.Threading.Thread.Sleep(5000);
Client.GetAsync("http://localhost:1234/cancel");
Console.ReadLine();
}
}
public class TestModule : NancyModule
{
CancellationTokenSource cts = new CancellationTokenSource();
public TestModule()
{
Get["/run", true] = async (parameters, ct) =>
{
Algorithm ag = new Algorithm();
Console.Write("Running Algorithm...\n");
var result = await Task.Run(() => ag.RunAlgorithm(cts.Token), cts.Token);
return Response.AsText(result.ToString());
};
Get["/cancel"] = _ =>
{
Console.Write("Cancel requested recieved\n");
cts.Cancel();
return Response.AsText("Foo");
};
}
}
class Algorithm
{
public Algorithm()
{
}
public int RunAlgorithm(CancellationToken cToken)
{
int min = Int32.MinValue;
while (min < Int32.MaxValue)
{
if (!cToken.IsCancellationRequested)
{
min++;
}
else
{
Console.Write("IsCancellationRequested true!\n");
cToken.ThrowIfCancellationRequested();
}
}
return min;
}
}
}
CreateLinkedTokenSource()
, чтобы упростить использование двух токенов одновременно. - person Peter Duniho   schedule 15.08.2016RunAlgorithm()
, и вместо этого имеете дело с двумя разными. Но без хорошего MCVE невозможно предложить, как решить проблему. - person Peter Duniho   schedule 15.08.2016int.MinValue
доint.MaxValue
менее чем за 5 секунд до вызова операции отмены. Во-вторых, вы уверены, что Нэнси создает только один экземплярTestModule
? Что произойдет, если вы сделаетеcts
полемstatic
? - person Peter Duniho   schedule 15.08.2016