I am writing a bot with a component that simulates typing by notifying the user "Bot is typing...". To do this the service provider that hosts the bot has to be notified every 10 seconds that the bot is still working.
The number of seconds the bot is "typing" is simply determined by the length of the string divided by an arbitrary value of "characters per second".
var text = "This is my response!";
var alertServiceInSeconds = 10;
var delay = text.Length / (double) charactersPerSecond;
So two tasks have to be performed: sleeping the thread for the duration of delay
while calling a method every alertServiceInSeconds
.
I've attempted a couple of methods, but the bot seems to reply in delay + alertServiceInSeconds
seconds, rather than just delay
seconds. I must be missing something in this grade school math.
while Stopwatch.Elapsed
From: How to execute the loop for specific time
I feel like this method should hurt my soul because of the number of times Math.Abs
is called. Furthermore, TriggerTyping is being called more frequently than alertServiceInSeconds
.
var stopwatch = new Stopwatch();
stopwatch.Start();
while (stopwatch.Elapsed < TimeSpan.FromSeconds(delay))
{
if (Math.Abs((stopwatch.ElapsedMilliseconds * 1000) / alertServiceInSeconds % 1) == 0)
await client.TriggerTyping();
}
stopwatch.Stop();
await client.SendMessage(text);
Thread.Sleep
This seems to get the job done, but not accurately as previously noted.
for (var i = 0; i < delay; i++)
{
Thread.Sleep(TimeSpan.FromSeconds(1));
if (Math.Abs(i / alertServiceInSeconds % 1) == 0)
await client.TriggerTyping();
}
await client.SendMessage(text);
Questions:
- How does this cause the bot to "type" in
delay + alertServiceInSeconds
seconds? - Are the tactics of these approaches okay? A sleeping for loop and a while loop dependent on TimeSpan both seem flawed but I cannot ponder a better approach.