不同的线程共享一个对象

时间:2010-12-07 19:51:56

标签: c# multithreading

我有以下代码片段,由不同的线程访问。

         try
         {            
            this.RefreshSettings();
            DateTime lastChecked = DateTime.Now.AddMilliseconds(-1 * m_Settings.Interval);

            while (Run)
            {
                if ((DateTime.Now - lastChecked).TotalMilliseconds >= this.m_Settings.Interval)
                {
                    lastChecked = DateTime.Now;

                    if (this.ShouldNotify())
                    {
                        object LockObj = new object();

                        lock (LockObj)
                        {
                            this.Notify();
                        }
                    }
                }
                //Thread.Sleep(this.m_Settings.Interval);
            }
         }

如您所见,我只希望在每个给定的时间间隔(m_settings.Interval)之后调用ShouldNotify()方法。但是,我的问题是如果两个或多个线程调用了NotifyIfNecesarry函数,它们将共享lastChecked变量。因此,如果一个线程将其值重置为dateTime.Now,那么它也将重置为其他线程。

如何编写该方法,以便每个线程都维护自己的lastChecked?使用Thread.Sleep不是一个选项,因为当bool Run的值更改为false时,我需要循环立即退出。如果我有一个thread.Sleep,并且线程正在休眠,程序将不会退出,直到它检查while条件,因此m_settings.Interval可能有mak延迟。

4 个答案:

答案 0 :(得分:1)

对本地创建的对象lock没有任何意义。所有线程必须lock在同一个实例上,否则将不会同步。

以下代码无法按预期工作,因为运行此代码的所有线程都将拥有自己对新创建的object实例的本地引用。

object LockObj = new object();

lock (LockObj)
{
   this.Notify();
}

此外,由于lastChecked是本地值类型,因此每个线程拥有自己的副本。

答案 1 :(得分:1)

为什么不简单地使用计时器对象?

要么:System.Windows.Forms.Timer 或者:System.Threading.Timer

答案 2 :(得分:1)

您应跳过循环并使用例如System.Timers.Timer。你的锁也不合适。它应该在循环外创建而不是每个实例。使用锁时,所有线程必须锁定在同一个对象上。

答案 3 :(得分:0)

  

我该如何编写该方法呢?   每个线程都保持自己的   lastChecked

你已经完成了这件事。

编码大猩猩说对了。

  

lastChecked变量是   local ...不共享局部变量   线程之间