c# - 通过保持线程模拟打字
问题描述
我正在编写一个带有一个组件的机器人,该组件通过通知用户“机器人正在打字......”来模拟打字。为此,必须每 10 秒通知托管该机器人的服务提供商该机器人仍在工作。
机器人“打字”的秒数简单地由字符串的长度除以“每秒字符数”的任意值来确定。
var text = "This is my response!";
var alertServiceInSeconds = 10;
var delay = text.Length / (double) charactersPerSecond;
所以必须执行两个任务:delay
在调用方法 every期间让线程休眠alertServiceInSeconds
。
我尝试了几种方法,但机器人似乎会在delay + alertServiceInSeconds
几秒钟内回复,而不仅仅是delay
几秒钟。我一定在这个小学数学中遗漏了一些东西。
而 Stopwatch.Elapsed
来自:如何在特定时间执行循环
Math.Abs
由于调用的次数,我觉得这种方法应该伤害我的灵魂。此外,TriggerTyping 的调用频率比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);
线程.睡眠
这似乎完成了工作,但不像前面提到的那样准确。
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);
问题:
- 这如何导致机器人在
delay + alertServiceInSeconds
几秒钟内“输入”? - 这些方法的策略好吗?依赖于 TimeSpan 的 sleep for 循环和 while 循环似乎都有缺陷,但我想不出更好的方法。
解决方案
您需要 alertServiceInSeconds % 10,而不是 alertServiceInSeconds % 1。
您还可以从任务调度库和队列中受益。
推荐阅读
- scala - 在 Scala 中模拟 Kafka 消费者
- javascript - 如何验证用户名输入表单 JavaScript
- javascript - 如何在 TypeScript 中使用第 3 阶段的功能?
- java - 构建自定义 SnakeYAML 构造函数以模块化方式反序列化 yaml 文件
- sql - Sql Join从A表中选择记录并从B表中选择符合条件的记录
- javascript - Outlook 插件无法获取附件
- git - 如何将一个大型 NextJS 项目推送到 GitHub
- javascript - Ajax自定义函数在wordpress中返回0
- javascript - jQuery dpTileSlider 超时功能不起作用
- asp.net - 单选按钮值不会进入数据库