【问题标题】:Show message in specified time在指定时间显示消息
【发布时间】:2021-03-03 05:43:57
【问题描述】:

我正在制作一个电报 C# 机器人,我想要我的机器人锁定组,我为此及其工作使用时间跨度,但我希望在锁定组向用户显示消息之前正好五分钟,但我的机器人没有自动发送任何消息. 我是初学者,没有在网上找到任何帮助。

感谢您的帮助。

TimeSpan Start = new TimeSpan(20,0,0);
TimeSpan End = new TimeSpan(21,0,0);
TimeSpan now = DateTime.Now.TimeOfDay;

TimeSpan risingStart1 = new TimeSpan(19, 55, 0);
            

if (now == risingStart1)
{            
    Bot.SendTextMessageAsync(e.Message.Chat.Id , "Group will lock for 5 min.");
}
else if (Start < now && now < End)
{
    Bot.DeleteMessageAsync(e.Message.Chat.Id, e.Message.MessageId);
}

PS:锁定组的时间跨度工作。

【问题讨论】:

  • 您的机器人是否一直在运行(如 Windows 服务)?在那个机器人上,你需要在给定的时间执行一些动作,是吗?
  • 请提供一个最小可重现示例stackoverflow.com/help/minimal-reproducible-example
  • 是的,我的机器人一直在运行。并且在给定的时间内应该做一些工作,比如发送消息或删除消息。

标签: c# api telegram-bot


【解决方案1】:

检查这是否有帮助:

public class Repeater
{
    private readonly List<DateTime> _checkpoints;
    private readonly Action _action;
    private readonly Func<Task> _asyncAction;
    private readonly Timer _timer;

    private Thread _processingThread;

    public Repeater(List<DateTime> checkpoints, Action action)
    {
        _checkpoints = checkpoints;

        _timer = new Timer
        {
            AutoReset = false,
            Enabled = false
        };
        _timer.Elapsed += TimerCheckpoint_Elapsed;
        _timer.Elapsed += CalculateNextExecution;

        _action = action;
        _asyncAction = null;
    }

    public Repeater(List<DateTime> checkpoints, Func<Task> action)
    {
        _checkpoints = checkpoints;

        _timer = new Timer
        {
            AutoReset = false,
            Enabled = false
        };
        _timer.Elapsed += TimerCheckpoint_Elapsed;
        _timer.Elapsed += CalculateNextExecution;

        _asyncAction = action;
        _action = null;
    }

    public void Start()
    {
        ReinitializeTimer();
    }

    public void Stop()
    {
        //_thrProcessaCheckpoints?.Abort();
        _timer?.Stop();
        _timer?.Dispose();
    }
    
    private void TimerCheckpoint_Elapsed(object sender, ElapsedEventArgs e)
    {
        if (_processingThread != null && _processingThread.IsAlive) return;

        _processingThread = new Thread(async () => await ThreadStart())
        {
            IsBackground = true,
            Name = "Timer Processing Thread"
        };

        try { _processingThread.Start(); } catch { /* ignored */ }
    }

    private async Task ThreadStart()
    {
        if (_asyncAction == null)
            _action();
        else
            await _asyncAction();
    }

    private void CalculateNextExecution(object sender, ElapsedEventArgs e)
    {
        ReinitializeTimer();
    }

    private void ReinitializeTimer()
    {
        _timer.Interval = CalculateNextInterval(_checkpoints);
        _timer.Start();
    }

    private static double CalculateNextInterval(List<DateTime> checkpoints)
    {
        double min = double.MaxValue;
        var dateTime = DateTime.Now;

        // Calculate how much time is left to the next checkpoint
        foreach (var date in checkpoints)
        {
            TimeSpan timeForNextCheckpoint;

            // If it's in the same time, calculate how much time is left
            if (date.TimeOfDay > dateTime.TimeOfDay)
                timeForNextCheckpoint = date.TimeOfDay - dateTime.TimeOfDay;
            // If not, calculate how much time is left, counting a day
            else
                timeForNextCheckpoint = TimeSpan.FromHours(24) - (dateTime.TimeOfDay - date.TimeOfDay);

            if (Math.Abs(timeForNextCheckpoint.TotalMilliseconds) < min)
            {
                min = Math.Abs(timeForNextCheckpoint.TotalMilliseconds);
            }
        }

        return min;
    }
}

用法:

var myRepeater = new Repeater(new List<DateTime>{ new DateTime(2020,19,11, 19, 55, 00) }, () => MyMethodCall());
myRepeater.Start(); // call on your application start
myRepeater.Stop(); // call on your application stop

您只需要提供包含您的任务需要执行的小时数的日期时间列表,以及将在该时间执行的方法。构造函数还有一个重载,可以在需要时接收异步方法。

var myAsyncRepeater = new Repeater(_cfg.ConfiguracaoBaixaAdiamentos.Checkpoints,
            async () => await MyMethodCallAsync());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-11
    相关资源
    最近更新 更多