Как остановить бесконечный цикл?
Есть телеграмм-бот, у него есть команда, которая выполняется бесконечно, пока не придет апдейт с командой "/stop".
public override async void Execute(String command, Message message, ITelegramBotClient client, State state)
{
if (message.Text == "/stop")
StopLoop();
if(message.Text == "/start")
StartLoop(message,client);
}
private CancellationTokenSource _cts;
private async Task RunLoopAsync(CancellationToken token,Message message, ITelegramBotClient client )
{
try
{
while (true)
{
await client.SendTextMessageAsync(message.Chat.Id, "send", cancellationToken: token);
await Task.Delay(10000, token);
}
}
catch (OperationCanceledException)
{ }
}
private async void StartLoop(Message message, ITelegramBotClient client)
{
if (_cts != null)
return;
try
{
using (_cts = new CancellationTokenSource())
{
await RunLoopAsync(_cts.Token,message,client);
}
}
catch (Exception ex)
{
// ... ex.Message
}
_cts = null;
}
private void StopLoop()
{
_cts?.Cancel();
}
Для остановки цикла, я взял пример отсюда: пример
Но это не помогает. Что посоветуете сделать, чтобы можно было остановить этот цикл?
Ответы (1 шт):
Автор решения: Alex
→ Ссылка
Спасибо @aepot за догадки, ибо они помогли. Для успешного окончания цикла, у меня в коде нужно добавить конечный автомат:
public override async void Execute(String command, Message message, ITelegramBotClient client, State state)
{
state.ActionCommand = "/start";
var searchState = await _context.SearchState.FindAsync((e => e.UserId == message.Chat.Id))
.Result.FirstOrDefaultAsync()??new SearchState(){_cts = new CancellationTokenSource()};
_cts = searchState._cts;
if (message.Text == "/stop")
{
searchState.IsWork = "false";
await _stateMachine.DeleteState(message.Chat.Id);
await _context.SearchState.ReplaceOneAsync((f=>f.UserId == message.Chat.Id),searchState);
await client.SendTextMessageAsync(message.Chat.Id, "end");
StopLoop();
}
if (message.Text == "/start")
{
searchState.UserId = message.Chat.Id;
searchState.IsWork = "true";
await _context.SearchState.InsertOneAsync(searchState);
StartLoop(message, client);
}
}
private CancellationTokenSource _cts;
private async Task RunLoopAsync(CancellationToken token,Message message, ITelegramBotClient client )
{
try
{
while (true)
{
var find = await _context.SearchState.FindAsync((e => e.UserId == message.Chat.Id)).Result.FirstOrDefaultAsync()??new SearchState();
if (find.IsWork == "false")
{
await _context.SearchState.DeleteOneAsync(f => f.UserId == message.Chat.Id);
return;
}
await _parserWorker.Work(message, client, message.Chat.Id);
await Task.Delay(120000, token);
}
}
catch (OperationCanceledException)
{ }
}
private async void StartLoop(Message message, ITelegramBotClient client)
{
try
{
using (_cts = new CancellationTokenSource())
{
await RunLoopAsync(_cts.Token,message,client);
}
}
catch (Exception ex)
{
// ... ex.Message
}
_cts = null;
}
private void StopLoop()
{
_cts?.Cancel();
}