C#使用锁实践

C#使用锁实践,c#,multithreading,locking,C#,Multithreading,Locking,我的应用程序中有一个包含大量代码的关键部分: 在threadMethod中锁定访问的更好方法是: A) 锁定所有块: private object locker = new object(); private void threadMethod() { while(true) { lock(locker) { // do work - a lot of code here } Thread.Sleep(2000);

我的应用程序中有一个包含大量代码的关键部分: 在threadMethod中锁定访问的更好方法是:

A) 锁定所有块:

private object locker = new object();

private void threadMethod()
{
   while(true)
   {
      lock(locker)
      {
         // do work - a lot of code here
      }
      Thread.Sleep(2000);
   }
}
B) 使用其他锁定访问成员
可以工作

 private static object locker = new object();
 private bool canWork;
 private bool CanWork
 { 
     get { lock(locker) { return this.canWork; } }
     set { lock(locker) { this.canWork = value; } } 
 }

  private void threadMethod()
  {
     while(true)
     {
        if(CanWork)
        {
           // do work - a lot of code here
        }
        Thread.Sleep(2000);
     }
  }
在代码的某个地方

CanWork = false;

第二种方法可能会导致比赛条件。你的“大量代码”能被分成几个关键/非关键块吗?

两者都不是特别好

  • 第一种方法的缺点是你需要长时间持有锁
  • 第二种方法的缺点是,检查后状态可能会发生变化

相反,尝试将不可变参数传递给方法(例如数据的副本)。在构造参数和收集结果时,您可能仍然需要锁定,但这希望是一个更短的时间段。

我将使用监视器。另外,你真的想要while(true),因为这将永远重复吗

  private object syncObject = new object();

  private void threadMethod()
  {
   bool tryToRun = true;
   while(tryToRun)
   {
    if(Monitor.TryEnter(syncObject))
    {
     tryToRun = false;

     // do work - a lot of code here

     Monitor.Exit(syncObject);
    }
    else
    {
     Thread.Sleep(2000); // Possibly knock this up the how long you expect the lock to be held for.
    }
   }
  }
est链接:

最好的用法是 -声明一个新的私有同步对象
-使用“lock(synObject){code here…}”

这两段代码的语义完全不同。请告诉我们更多关于您正在尝试执行的操作,我们将告诉您哪一段代码(如果有)符合您的需要。在属性setters/getter中使用lock语句似乎会导致灾难。同时,请检查您是否真的需要完全查看它,或者是否可以使用类似re的方法aderWriterLockSlim@MattiasK-我不明白为什么这是“灾难配方”-你能解释一下吗?从我的理解Monitor.TryEnter()来看,Monitor不是一个不那么智能的锁吗更好的方法是,当应用程序正在等待获取锁时,它不会暂停。如果另一个线程拥有锁,它只会返回false。然后,您可以在自己的时间稍后重试。在第二种情况下,当“CanWork”成员的状态更改时,工作将在下一个“while”期间完成“循环-哪里有缺点?@UGEEN:在读取值之后,但在实际开始处理该值之前,布尔值可能会变为false(可能是因为另一个线程恰好在同一时间开始处理该值)。在这种情况下,可能会有两个线程执行相同的工作,并且可能会干扰彼此的工作。boolean已锁定-您是指在读取boolean状态后直接发生的情况吗,但在检查“while”条件之前?@UGEEN:我的意思是布尔值在读取后,但在计算
if
语句之前可以更改。因此,没有简单的方法-感谢您的时间和回复。是的,但为了保持代码的可读性,我试图避免这种情况-现在我越来越相信,这将很困难