У меня есть функция, которая начинает тестирование. Эта функция содержит цикл «Время» и может занять до 15 минут, но тесты могут закончиться раньше, или клиент может быть отключен. Если одна из этих вещей произойдет, я хочу запустить функцию, которая отменяет эту цикл, но не совсем уверен, как это сделать.public class MyHub : Hub
{
private CancellationTokenSource cancellationTokenSource;
public async Task StartLongRunningTask()
{
cancellationTokenSource = new CancellationTokenSource();
try
{
await LongRunningTask(cancellationTokenSource.Token);
// Task completed successfully
}
catch (TaskCanceledException)
{
// Task was canceled by the client
// Handle cancellation logic here
}
finally
{
cancellationTokenSource.Dispose();
}
}
public void CancelLongRunningTask()
{
cancellationTokenSource?.Cancel();
}
private async Task LongRunningTask(CancellationToken ct)
{
// Your long-running task implementation
// Ensure to check the cancellation token periodically and stop processing if canceled
while (!ct.IsCancellationRequested)
{
await Task.Delay(1000, cancellationToken);
// Continue with other work...
}
}
}
< /code>
Это не работает, и я не совсем уверен, почему. Каким -то образом, если я позвоню в CancellongRunningTask, ничего не случится. Я добавил несколько журналов, чтобы убедиться, что функция была вызвана, и это было, но хотя в нем говорится, что в CancellongrunningTask. Это не отменено в реальной LongrunningTask. Может ли кто -нибудь помочь мне здесь?public class DeviceTestHub : Hub
{
private readonly ILogger _logger;
private readonly IMemoryCache _cache;
private readonly IMessageProcessor _messageProcessor;
private readonly IDeviceTestHandler _deviceTestHandler;
private readonly TimeSpan _cacheExpirationTime = TimeSpan.FromMinutes(15);
private CancellationTokenSource _cts;
public DeviceTestHub(IDeviceTestHandler deviceTestHandler, IMemoryCache memoryCache,
ILogger logger, IMessageProcessor messageProcessor)
{
_cache = memoryCache;
_logger = logger;
_messageProcessor = messageProcessor;
_deviceTestHandler = deviceTestHandler;
}
public async Task StartTesting(string imei, DateTime startDate)
{
try
{
_cts = new CancellationTokenSource();
await LongRunningTest(imei, startDate, _cts.Token);
}
catch (OperationCanceledException e)
{
await Clients.Caller.SendMessage($"Test took longer than 12 minutes and is cancelled for imei: {imei}");
await _messageProcessor.Dispose(imei);
await OnDisconnectedAsync(e);
}
catch (Exception ex)
{
_logger.LogError($"Exception occurred in websocket for imei: {{Imei}}, {nameof(Exception)}: {{Exception}}",
imei, ex.Message);
await _messageProcessor.Dispose(imei);
await Clients.Group(imei).SendMessage(ex.Message);
}
finally
{
_cts.Dispose();
}
}
public void CancelTesting()
{
_logger.LogInformation("================================= Cancel testing =================================");
_cts?.Cancel();
}
private async Task LongRunningTest(string imei, DateTime startDate, CancellationToken ct)
{
//Clear session before start testing
await _messageProcessor.Dispose(imei);
//Do the actual tests
//Get raw message from Message Session, send it to the frontend but also pass it to the test handler
var socketTests =
_cache.Get($"{MemoryCacheKeys.DeviceTest}-{imei}")
?? await _deviceTestHandler.GetTests(imei);
var messages = new List();
_cts.Token.ThrowIfCancellationRequested();
while (!_cts.IsCancellationRequested)
{
if (socketTests.Any(x => x.State == State.NotStarted))
{
//Loop through tests and return the first test that is not started yet and set it to loading
var test = _deviceTestHandler.SetTestActive(socketTests, _cts.Token);
//Send the changed test to frontend
if (test != null) await Clients.Group(imei).UpdateTest(test);
}
//Get raw message from Message Session
var message = await _messageProcessor.ReceiveMessage(imei, _cts.Token);
if (message.IsNullOrEmpty() && messages.IsNullOrEmpty())
{
await Task.Delay(3000, _cts.Token);
continue;
}
if (!message.IsNullOrEmpty())
{
var rawMsg = await _deviceTestHandler.ConvertMessageToRawMessage(message);
//Send raw message to frontend
await Clients.Caller.SendRawMessage(JsonSerializer.Serialize(rawMsg));
messages.Add(rawMsg);
}
var activeTest = socketTests.FirstOrDefault(x => x.State is State.Loading or State.Inprogress);
if (activeTest is null) return;
var executedTest = await _deviceTestHandler.ExecuteTest(imei, activeTest, messages, startDate);
if (executedTest != null)
{
//Send the changed test to frontend
await Clients.Group(imei).UpdateTest(executedTest);
}
_cts.Token.ThrowIfCancellationRequested();
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/767 ... -i-do-this