【问题标题】:How to acquire multiple locks in VS2012 without messing up indentation如何在 VS2012 中获取多个锁而不弄乱缩进
【发布时间】:2014-11-12 20:47:53
【问题描述】:

这看起来像一个愚蠢的问题,但我无法找到解决方案。

我的问题是 C# 不允许在单个 lock 语句中获取多个锁。这行不通:

lock (a, b, c, d)
{
    // ...
}

相反,它似乎需要大量的缩进才能做到这一点:

lock (a)
    lock (b)
        lock (c)
            lock (d)
            {
                // ...
            }

再加上代码已经存在的所有其他缩进级别(命名空间、类、方法、条件、循环……),这变得疯狂。因此,我想使用这种格式:

lock (a) lock (b) lock (c) lock (d)
{
    // ...
}

并保持我的理智。但是 Visual Studio(我正在使用 2012)不会听说它。一旦我输入任何右括号,上面的内容就会变成一些愚蠢的东西,比如:

lock (a) lock (b) lock (c) lock (d)
                  {
                      // ...
                  }

而且我似乎无能为力。有什么办法可以做到这一点?

【问题讨论】:

  • 您是否安装了 Resharper 或类似软件?
  • @DaveZych 不,我不使用任何第三方模块。
  • 希望您不要经常这样做。获取多个锁可能是让自己陷入死锁情况的最简单方法。
  • 不是你的问题的答案.. 因此是评论.. 你为什么要使用这么多锁开始.. 你要么有非常复杂和罕见的场景.. 要么这是一个危险信号。
  • 你可以关闭自动格式化....

标签: c# visual-studio visual-studio-2012 auto-indent


【解决方案1】:

只是一个想法:-)

static class LockAndExecute
{
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    static void _gen(Action a, object[] objs, int i = 0){

        bool lockWasTaken = false;
        var temp = objs[i];
        try { 
            Monitor.Enter(temp, ref lockWasTaken); 
            if(i + 1 >= objs.Length) 
                a();
            else
                _gen(a, objs, i + 1);
        }
        finally 
        { 
            if (lockWasTaken) 
                Monitor.Exit(temp); 
        }
    }

    public static void Do(object[] objectsToLock, Action action){
            _gen(action, objectsToLock);
    }
}

及用法;

LockAndExecute.Do(new[]{a, b}, () => {
    Console.WriteLine("Eww!");
});

【讨论】:

    【解决方案2】:

    一次使用这么多锁只是要求死锁。哎呀,即使一次获得两个不同的锁也会有这种风险。

    至少,您应该非常非常小心,只在每次获取多个锁的地方以完全相同的顺序获取这些锁。

    此外,“漂亮的格式”在旁观者的眼中。也就是说,每个人对什么是最好的都有自己的想法。但是,除非您特别要求(例如通过触发自动格式化规则或显式自动格式化),否则以下内容应该可以工作,VS 不会弄乱它:

    lock (a)
    lock (b)
    lock (c)
    lock (d)
    {
    }
    

    您也可以将此方法与 using 语句一起使用(其中更常见的是连续有多个语句),VS IDE 已经预料到了。

    【讨论】:

    • 几乎可以,但不完全:最后一个锁会自动缩进。
    【解决方案3】:

    您可以通过更改代码来解决 IDE 令人讨厌的行为,尽管更改代码以解决 IDE 行为的想法让我有点良心不安。如果它是一个玩具项目,但不是其他开发人员可能从事的任何严肃的项目,我会这样做。

    使用IDisposable 实现来实现锁。 using 语句没有 lock 语句那样烦人的缩进问题。

    class myLock : IDisposable
    {
        private object _obj;
    
        public myLock(object obj)
        {
            _obj = obj;
            System.Threading.Monitor.Enter(obj);
        }
    
        public void Dispose()
        {
            System.Threading.Monitor.Exit(_obj);
            _obj = null;
        }
    
        public static void example()
        {
            var obj1 = new object();
            var obj2 = new object();
            var obj3 = new object();
    
            lock (obj1)
                lock (obj2)
                    lock (obj3)
                    {
                        // Stupid indentation >:(
                    }
    
            using (new myLock(obj1))
            using (new myLock(obj2))
            using (new myLock(obj3))
            {
                // Ahhhh... :-)
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2014-10-16
      • 1970-01-01
      • 2021-04-05
      • 1970-01-01
      • 2011-10-28
      • 2017-10-18
      • 1970-01-01
      • 1970-01-01
      • 2017-08-25
      相关资源
      最近更新 更多