Как остановить telegram бота
Предположим у нас есть такой код:
public Bot() { }
private static string tokenToAPI = "<token>";
private static ITelegramBotClient? _botClient;
// Это объект с настройками работы бота. Здесь мы будем указывать, какие типы Update мы будем получать, Timeout бота и так далее.
private static ReceiverOptions? _receiverOptions;
public async Task Run()
{
_botClient = new TelegramBotClient(tokenToAPI);
_receiverOptions = new ReceiverOptions
{
AllowedUpdates = new[]
{
UpdateType.Message
},
ThrowPendingUpdates = false,
};
using CancellationTokenSource cts = new CancellationTokenSource();
_botClient.StartReceiving(UpdateHandler, ErrorHandler, _receiverOptions, cts.Token); // Запускаем бота
User bot = await _botClient.GetMeAsync();
Notifier.SendNote($"Бот ` {bot.Username} ` успешно запущен и инициализирован\n");
Notifier.SendBoolean(true);
await Task.Delay(-1); // Устанавливаем бесконечную задержку, чтобы наш бот работал постоянно
}
И вот пара методов:
private static async Task UpdateHandler(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken)
{
try
{
switch (update.Type)
{
case UpdateType.Message:
{
// Какая-то логика
return;
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
private static Task ErrorHandler(ITelegramBotClient botClient, Exception error, CancellationToken cancellationToken)
{
// Тут создадим переменную, в которую поместим код ошибки и её сообщение
string ErrorMessage = error switch
{
ApiRequestException apiRequestException
=> $"Telegram API Error:\n[{apiRequestException.ErrorCode}]\n{apiRequestException.Message}",
_ => error.ToString()
};
Console.WriteLine(ErrorMessage);
return Task.CompletedTask;
}
Буквально код из Хабра
Мой вопрос состоит в следующем: каким образом можно написать такой метод (не обязательно в этом же классе), который полностью остановит бота. После вызова такого метода бот не должен проявлять признаки жизни и для повторного его запуска нужно будет вызвать метод Run()
Ответы (1 шт):
Автор решения: aepot
→ Ссылка
Например с помощью TaskCompletionSource
.
private TaskCompletionSource tcs;
public async Task Run()
{
if (tcs is not null)
throw new InvalidOperationException("Bot is already running.");
tcs = new();
// убираем await Task.Delay(-1);
// добавляем вот это
await tcs.Task;
tcs = null;
// здесь можно выполнить все остановки, какие требуются, например:
cts.Cancel();
}
public void Stop()
{
tcs?.SetResult() ?? throw new InvalidOperationException("Bot is not running.");
}