【问题标题】:Lock two timers on different object将两个计时器锁定在不同的对象上
【发布时间】:2017-06-08 06:00:54
【问题描述】:

我有几个对象需要在不同的时间执行相同的功能。其中有些对象是互斥的,有些则不是。

简而言之,我只用两个计时器来说明这个简短的例子

这两个计时器是否并行工作?还是我应该使用不同的方法?

class MyTimer:Timer
{
   private static int count=0;
   public int Id {get; private set;}
   public MyTimer(){ Id= count++;}
}

...
object[] lockers = new object[2]{new object(), new object()};
MyTimer[] timers = new MyTimer[2]{ new MyTimer(), new MyTimer()};
...
/* somewhere */
timers[0].Elapsed += Time_Elapsed;
timers[1].Elapsed += Time_Elapsed;
timers[0].Start();
timers[1].Start();
...
private void Time_Elapsed(object sender, ElapsedEventArgs e)
{
    MyTimer timer = sender as MyTimer;
    lock(lockers[timer.Id])
    {
        /* part of code depends on timer.Id*/
    }
}

在 Kennyzx 回答后编辑(我不想写太多代码,但我不清楚上面我想问什么):

interface IWorker 
  {
   void DoSomething();
  }
class MyTimer:Timer
{   
   public int Id {get; private set;}
   public IWorker Worker;
   public MyTimer(int id){ Id=id;}
}
...
object[] lockers = new object[2]{new object(), new object()};
MyTimer[] timers = new MyTimer[3]{ new MyTimer(0), new MyTimer(1),new MyTimer(1)};
...
/* somewhere */
timers[0].Elapsed += Time_Elapsed;
timers[1].Elapsed += Time_Elapsed;
timers[2].Elapsed += Time_Elapsed;

timers[0].Worker = Worker_A; // implement IWorker
timers[1].Worker = Worker_B; // implement IWorker
timers[2].Worker = Worker_C; // implement IWorker
timers[0].Start();    timers[1].Start();    timers[2].Start();
...
private void Time_Elapsed(object sender, ElapsedEventArgs e)
{
    MyTimer timer = sender as MyTimer;
    lock(lockers[timer.Id])
    {
        timer.Worker.DoSomething();
    }
}

在这个新示例中,Worker_B 和 Worker_C 是互斥的(因为 timer.Id 相同)。但是 Worker_A 可以与它​​们并行工作。 实现它的正确方法吗?

【问题讨论】:

    标签: c# multithreading timer locking


    【解决方案1】:

    这两个定时器是并行工作的吗?

    对于 System.Timers.Timer,Elapsed 事件在 ThreadPool 线程上引发,这意味着事件处理程序可以并行运行。

    但是您的lock 声明有点问题,您如何保证互斥?应该锁定对象的同一个实例。

    object locker = new object();
    
    ...
    
    private void Time_Elapsed(object sender, ElapsedEventArgs e)
    {
        lock(locker)
        {
            ...
    

    【讨论】:

    • 我更新了这个问题,添加了一个更详细的问题。我希望我现在清楚
    • 您的代码可以工作,但是从 OO 的角度来看,这些类的设计并不好。具体来说,MyTimer 的 Id 属性和 lockers 数组起到同步的作用,但它们与必须互斥访问的真实资源没有直接关系。 StackExchange 中有a site 用于代码审查,您可以在那里发布您的代码并寻求帮助以改进您的代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-21
    • 1970-01-01
    • 2019-02-18
    • 1970-01-01
    • 2022-11-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多