【发布时间】:2019-04-10 20:11:14
【问题描述】:
我的目标是编写一个代码 sn-p,让我可以在并发环境中独占访问对象(f.ex 一个 txt 文件)。考虑到这一点,我正在测试使用两个 System.Timers 计时器构建的简单程序。两个计时器的事件处理程序共享同一个锁对象(请参阅下面的代码)。
定时器以不同的时间间隔同时启动,定时器 1 为 3 秒,定时器 2 为 1 秒。 Timer1 应该只工作一个周期,在此期间它的事件处理程序将休眠 10 秒,从而保持锁定。
令我惊讶的是,当锁被释放时,我并没有把所有的事件都堆积在内存中 timer2 事件(只有应用程序。每个其他事件)。我想,虽然 timer1 的事件处理程序有锁,但 timer2 的事件在内存中堆叠。但这显然不是真的。为什么一些 timer2 事件消失了?
class Program
{
static int counter = 0;
static readonly object locker = new object();
System.Timers.Timer timer1;
System.Timers.Timer timer2;
static void Main(string[] args)
{
Program p = new Program();
p.timer1 = new System.Timers.Timer(3000);
p.timer1.Elapsed += new ElapsedEventHandler(p.Timer1EventHandler);
p.timer1.Start();
p.timer2 = new System.Timers.Timer(1000);
p.timer2.Elapsed += new ElapsedEventHandler(p.Timer2EventHandler);
p.timer2.Start();
ThreadPool.SetMaxThreads(50, 50);
Console.ReadLine();
}
void Timer1EventHandler(object sender, ElapsedEventArgs e)
{
timer1.Stop();
DoThingsForTimer1Event();
}
void DoThingsForTimer1Event()
{
lock (locker)
{
Console.WriteLine(DateTime.Now + " Timer1 event started." + " Current thread number " + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(10000);
Console.WriteLine(DateTime.Now + " Timer1 event finished. Lock released.");
}
}
void Timer2EventHandler(object sender, ElapsedEventArgs e)
{
counter++;
lock (locker)
{
Console.WriteLine(DateTime.Now + " Timer2 event fired. Current thread number " + Thread.CurrentThread.ManagedThreadId +
" Counter=" + counter);
}
}
}
【问题讨论】:
-
I don't get all stacked in memory timer2 events你到底是什么意思,这似乎是你所期望的工作 -
虽然除非我读错了,但这正是它所做的
-
如果您对 3-8 的去向感到困惑 - 将
++移入锁内。 -
从实用的角度来看,你也不能安全地同时在多个线程中使用
++。所以如果你不把它们放在锁里,你必须使用Interlocked.Increment。这对您来说还不是一个大问题(因为竞争条件很少见),但它仍然是一个问题。 -
我认为它只是厌倦了亲自给你线程,我的意思是线程池不会尽可能快地放弃线程。我认为如果您将时间更改为 5 秒锁定,它很可能会按预期工作
标签: c# concurrency locking system.timers.timer