问题
I am making a telegram C# bot and I want my bot lock group and I use timespan for this and its work but I want exactly five minutes before lock group shows a message for users but my bot didn't send any messages automatically. I am so beginner and didn't find any thing online for help.
Thank you for your help.
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: Timespan work for locking group.
回答1:
Check if this helps:
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;
}
}
Usage:
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
You just need to provide a list of datetimes containing the hours that your task needs to be executed, and a method that will be executed at such time. The constructor also have an overload that receives an async method should you need it.
var myAsyncRepeater = new Repeater(_cfg.ConfiguracaoBaixaAdiamentos.Checkpoints,
async () => await MyMethodCallAsync());
来源:https://stackoverflow.com/questions/64918790/show-message-in-specified-time