关于锁的问题

stevenjin 2018-04-18 09:33:28
在使用定时任务时,有时数据量少,可能1秒内多次执行方法。
这里想用锁的方案,即在方法没有执行完之前,不可进入锁内的代码。
但实际是1钞内进入了3到4次(触发器设置了为100毫秒)。
请教锁的正确用法,谢谢!

this.Timer = new System.Timers.Timer(100); //触发间隔100毫秒
this.Timer.Elapsed += new ElapsedEventHandler(Timer_Elapsed);

private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{//100毫秒触发
try
{
UpdateEveryHour();
}

catch (Exception ex)
{
loginfo.Info(ex.Message);
}
}

static object locker = new object();
private static void UpdateEveryHour()
{
lock (locker)//防止并发(1秒内执行多次)
{
//清理数据.......
}

}


...全文
311 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
xuzuning 2018-04-18
  • 打赏
  • 举报
回复
引用 5 楼 stevenjin 的回复:
[quote=引用 3 楼 closurer 的回复:] 代码里面没有体现等待 1秒 这个逻辑。
补充一下,我漏写了。这里就是在整点执行,但在第0秒时,速度快的话会在这1秒内执行数次。 if (DateTime.Now.Minute == 00 & DateTime.Now.Second == 00) { UpdateEveryHour(); }[/quote] 自己对自己都不负责,还指望别人对你负责?! 你的定时器是 触发间隔100毫秒 而你却用分辨率为秒的尺子去度量,不觉得很滑稽吗? 尺子的最小刻度要比被测量的物体小,才能进行测量 至少得 DateTime.Now.Millisecond == nnnn 才行 但这还有一个问题:如果 System.Timers.Timer 是在 nnnn+1 那一刻启动的,并且假定 System.Timers.Timer 的计时精度是准确的,那么你就永远都不可能满足 DateTime.Now.Millisecond == nnnn 了
闭包客 2018-04-18
  • 打赏
  • 举报
回复
引用 9 楼 stevenjin 的回复:
[quote=引用 7 楼 closurer 的回复:] 你可以 Thread.Sleep(1000) 这样快速解决一下。但整个设计还是有点问题的。
1.Thread.Sleep(1000)放在什么位置 2.更好的方法应该怎样,谢谢![/quote] 放在整点执行的判断里面。
stevenjin 2018-04-18
  • 打赏
  • 举报
回复
引用 7 楼 closurer 的回复:
你可以 Thread.Sleep(1000) 这样快速解决一下。但整个设计还是有点问题的。
1.Thread.Sleep(1000)放在什么位置 2.更好的方法应该怎样,谢谢!
stevenjin 2018-04-18
  • 打赏
  • 举报
回复
引用 7 楼 closurer 的回复:
你可以 Thread.Sleep(1000) 这样快速解决一下。但整个设计还是有点问题的。
1.Thread.Sleep(1000)放在什么问题 2.有没有更好的方法,谢谢!
闭包客 2018-04-18
  • 打赏
  • 举报
回复
引用 5 楼 stevenjin 的回复:
[quote=引用 3 楼 closurer 的回复:] 代码里面没有体现等待 1秒 这个逻辑。
补充一下,我漏写了。这里就是在整点执行,但在第0秒时,速度快的话会在这1秒内执行数次。 if (DateTime.Now.Minute == 00 & DateTime.Now.Second == 00) { UpdateEveryHour(); }[/quote] 这样写不能保证 1秒只执行 1次的。
闭包客 2018-04-18
  • 打赏
  • 举报
回复
你可以 Thread.Sleep(1000) 这样快速解决一下。但整个设计还是有点问题的。
stevenjin 2018-04-18
  • 打赏
  • 举报
回复
引用 3 楼 closurer 的回复:
代码里面没有体现等待 1秒 这个逻辑。
补充一下,我漏写了。这里就是在整点执行,但在第0秒时,速度快的话会在这1秒内执行数次。 if (DateTime.Now.Minute == 00 & DateTime.Now.Second == 00) { UpdateEveryHour(); }
xuzuning 2018-04-18
  • 打赏
  • 举报
回复
锁 不会阻止其他线程的进入,只是阻止多个线程同时进入
闭包客 2018-04-18
  • 打赏
  • 举报
回复
代码里面没有体现等待 1秒 这个逻辑。
stevenjin 2018-04-18
  • 打赏
  • 举报
回复
但现在的问题是,每次都进入 locker之内了。也就是说锁并没有阻止其他线程的进入,也就不会产生队列了,对吧?
xuzuning 2018-04-18
  • 打赏
  • 举报
回复
每100毫秒执行一次 UpdateEveryHour() 如果你的 //清理数据...... 动作不能在 100毫秒 之内完成的话,将会产生长长的等待队列。甚至可能导致系统崩溃
stevenjin 2018-04-18
  • 打赏
  • 举报
回复
引用 11 楼 xuzuning 的回复:
[quote=引用 5 楼 stevenjin 的回复:] [quote=引用 3 楼 closurer 的回复:] 代码里面没有体现等待 1秒 这个逻辑。
补充一下,我漏写了。这里就是在整点执行,但在第0秒时,速度快的话会在这1秒内执行数次。 if (DateTime.Now.Minute == 00 & DateTime.Now.Second == 00) { UpdateEveryHour(); }[/quote] 自己对自己都不负责,还指望别人对你负责?! 你的定时器是 触发间隔100毫秒 而你却用分辨率为秒的尺子去度量,不觉得很滑稽吗? 尺子的最小刻度要比被测量的物体小,才能进行测量 至少得 DateTime.Now.Millisecond == nnnn 才行 但这还有一个问题:如果 System.Timers.Timer 是在 nnnn+1 那一刻启动的,并且假定 System.Timers.Timer 的计时精度是准确的,那么你就永远都不可能满足 DateTime.Now.Millisecond == nnnn 了 [/quote] 你说的是对的,我用毫秒做判断时,发现 DateTime.Now.Millisecond相等不了,进不去的。 我这里假设这里最小单位是秒了,但程序却在这1秒内可以去执行多次。 我以为用lock可以阻止代码调用,其实理解错了。这种方式只能防止多个线程同时调用。 所以先采用睡眠的方式暂时解决。 大家还有更好的解决方案不妨告诉我,谢谢了!
正怒月神 2018-04-18
  • 打赏
  • 举报
回复
逻辑有问题,理解也有问题。 lock只是同时只有一个线程操作, 不代表其他线程不排队。

110,547

社区成员

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

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

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