Thread.Sleep(120000)是异步的?

谁学逆向工程 2018-06-25 08:32:52
有个Timer控件,interval 是100。代码大致如下
private void OnTimer(object sender, EventArgs e)
{
while(reader.Read())//读取数据库下一行电话号码
{
1、调用阿里云给手机发送一条短信
2、if(现在是21点07分)
Thread.Sleep(120000);
}
}

运行这个代码后,我手机收到了3条短信。
...全文
336 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
本人QQ-554433626 2018-06-25
  • 打赏
  • 举报
回复
你的reder有多少你的电话号码就会发多少次(不考虑阿里短信同一号码一分钟一次的限制)
至于有两个你的电话,却会收到3条是不可能的(最多两条,如果时间判断为true且第一条是你的短信,两分钟后你的另一条短信会发送,如果时间判断为false应该只收到一条),reader.Read()读完while循环是进不了的,除非你的reder在发生改变(也可能是阿里的短信发送延迟,并不全是这次执行程序发送的短信)

阿里云默认流控:短信验证码:使用同一个签名,对同一个手机号码发送短信验证码,支持1条/分钟,5条/小时,累计10条/天。
本人QQ-554433626 2018-06-25
  • 打赏
  • 举报
回复
Thread.Sleep是同步的。Sleep的是主线程,代表的是在接下来的120000毫秒内不参与cpu的资源的竞争
如果是连续发送三条那就是 "if(现在是21点07分)" 没进,while会直接循环完 然后你的timer就没有意义了 除非reader改变
xuzuning 2018-06-25
  • 打赏
  • 举报
回复
Timer.tick 事件触发的响应程序是在子线程中运行的
连续的 Timer.tick 响应程序都是独立的子线程,当然对于你的这个应用,由于 reader 是全局的,所以整体行为受制于 reader 是否有效

阿里云是否会过滤重复号码,我不得而知。但不能对相同的号码发送短信,本身就是不合情理的

至于 有两个我电话,却会收到3条。那是出现了共享冲突(在 reader 记录移动尚未完成时,又执行了读操作)
  • 打赏
  • 举报
回复
ADO.NET 基本编程机制我补充一下,程序中会嵌套、以及多线程地访问数据库连接,所以连接根本不是什么“全局唯一 DbConnection”的。如果你用一个连接就“共享”了各种数据库操作,可见你没有在一个数据库的 DbReader 访问过程中同时访问过数据库其它查询,也没有接触过并发多线程程序。否则你一定知道在实例化一个 Reader 之前一定要单独实例化一个 DbConnection 数据库连接。
  • 打赏
  • 举报
回复
访问数据库ADO.NET引擎,要及时打开逻辑连接、及时释放连接,要在 using(){....}结构创建数据库连接,然后从连接再创建 DbDataReader。

进行轮询起码要等一次操作结束之后才开始下一次操作。

通常实际的程序是事件通知(当有信息需要发送时直接通知开始操作,而根本不用什么数据库)的,刚学编程的人才会用轮询来模拟事件机制。原因是完全没有学习过事件驱动设计的相关知识。

既然要 while 循环去“发送下一条短信”,为什么又要 Thread.Sleep 卡死 while 循环?既然你知道 Sleep 应该是卡死了线程,也就知道只有刚学编程的人才会卡死线程。而设计实际的程序的人,是安排2分钟以后定时启动发送短信操作,而不是什么Sleep。

可以这样说,滥用 while(包括滥用 timer)然后在while 里边写 Sleep,这是一个一眼就能看出来的自学编程的大毛病,在软件工程设计上缺少编程模式和技能。
正怒月神 2018-06-25
  • 打赏
  • 举报
回复
引用 9 楼 xiaoyuanyuan2009 的回复:
[quote=引用 5 楼 hanjun0612 的回复:]
抱歉,前面没注意。
更正一下,

这里说的timer是System.Threading.Timer
thread.sleep: 将当前线程挂起指定的毫秒数。
timer每次都是开新线程去干活。所以你的thread.sleep根本没有影响所有的timer开启的线程。


而如果是System.Windows.Forms.Timer
那么只能等到上一次执行完了,才会继续执行后一个tick事件。
至于你这里的发送三条,我想可能是因为while中,先去发送短信,然后if判断没有进入,导致连续while发送了3条短信

你的意思是Sleep阻塞的是主线程,然后发短信的timer 是另一个线程,互不相干?[/quote]
不是这个意思,如果你是System.Windows.Forms.Timer 那么我怀疑是 if判断没有进入,导致了thread.sleep没有触发,而连续发送了3条短息。
谁学逆向工程 2018-06-25
  • 打赏
  • 举报
回复
引用 5 楼 hanjun0612 的回复:
抱歉,前面没注意。
更正一下,

这里说的timer是System.Threading.Timer
thread.sleep: 将当前线程挂起指定的毫秒数。
timer每次都是开新线程去干活。所以你的thread.sleep根本没有影响所有的timer开启的线程。


而如果是System.Windows.Forms.Timer
那么只能等到上一次执行完了,才会继续执行后一个tick事件。
至于你这里的发送三条,我想可能是因为while中,先去发送短信,然后if判断没有进入,导致连续while发送了3条短信

你的意思是Sleep阻塞的是主线程,然后发短信的timer 是另一个线程,互不相干?
谁学逆向工程 2018-06-25
  • 打赏
  • 举报
回复
引用 4 楼 xuzuning 的回复:
在 reader.Read() 读空查询结果前,短信总是要发送的
收到了3条短信 的原因是:查询结果集中有你3个号码

Thread.Sleep(120000); 只是推迟了下一条短信的发送
何况还是有条件执行的

有两个我电话,而且阿里云会过滤重复号码,我也有收到一条短信的时候
谁学逆向工程 2018-06-25
  • 打赏
  • 举报
回复
引用 3 楼 qq14923349 的回复:
1、调用阿里云给手机发送一条短信
这里异步了吧?

你是说发短信是异步的? Sleep是同步的?
  • 打赏
  • 举报
回复
无法理解各种杂乱的想当然的自学的人的路子,全局定义的 reader?100毫秒定时执行的过程中竟然还有while循环?while循环里边竟然还Thread.Sleep(120000)?

学习过软件基础课程(起码十几门课程)的人,因为收到了基础的解题训练,不这样写代码。
正怒月神 2018-06-25
  • 打赏
  • 举报
回复
抱歉,前面没注意。
更正一下,

这里说的timer是System.Threading.Timer
thread.sleep: 将当前线程挂起指定的毫秒数。
timer每次都是开新线程去干活。所以你的thread.sleep根本没有影响所有的timer开启的线程。


而如果是System.Windows.Forms.Timer
那么只能等到上一次执行完了,才会继续执行后一个tick事件。
至于你这里的发送三条,我想可能是因为while中,先去发送短信,然后if判断没有进入,导致连续while发送了3条短信

xuzuning 2018-06-25
  • 打赏
  • 举报
回复
在 reader.Read() 读空查询结果前,短信总是要发送的
收到了3条短信 的原因是:查询结果集中有你3个号码

Thread.Sleep(120000); 只是推迟了下一条短信的发送
何况还是有条件执行的
qq14923349 2018-06-25
  • 打赏
  • 举报
回复
1、调用阿里云给手机发送一条短信
这里异步了吧?
  • 打赏
  • 举报
回复
Timer是定时触发
按你这代码逻辑,只发3次已经是少了……
你是100ms执行一次代码,理论上你应该触发9~10次
  • 打赏
  • 举报
回复
自己设置断点调试一下。

110,537

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧