C# 锁定传递给方法的引用 - 不好的做法?

2024-04-30

我有一个类似的方法:

public static void DoSomething (string param1, string param2, SomeObject o) 
{
   //.....

   lock(o) 
   {
       o.Things.Add(param1);
       o.Update();
       // etc....
   }
}

几点:

  1. 以这种方式锁定是不好的做法吗?
  2. 我应该锁定一个private static object反而?
  3. 如果是这样,为什么?

为了最大限度地减少副作用,被锁定的对象不应该是被操作的对象,而应该是指定用于锁定的单独对象。

根据您的要求,有几种处理此问题的选项:

变体 A:私有锁定对象

如果您只是想确保DoSomething与并行实例不冲突DoSomething.

private static readonly object doSomethingLock = new object();

public static void DoSomething (string param1, string param2, SomeObject o) 
{
   //.....

   lock(doSomethingLock) 
   {
       o.Things.Add(param1);
       o.Update();
       // etc....
   }
}

变体 B:将锁定对象作为参数传递

如果可以访问,请选择此项o即使在外部也必须是线程安全的DoSomething,即,如果存在其他人编写方法的可能性DoSomethingElse它并行运行DoSomething并且不得干扰lock阻止DoSomething:

public static void DoSomething (string param1, string param2, SomeObject o, object someObjectLock) 
{
   //.....

   lock(someObjectLock) 
   {
       o.Things.Add(param1);
       o.Update();
       // etc....
   }
}

变体 C:创建 SyncRoot 属性

如果您可以控制实施SomeObject,将锁定对象作为属性提供可能会很方便。这样,您就可以实现变体 B,而无需传递第二个参数:

class SomeObject
{
    private readonly object syncRoot = new object();

    public object SyncRoot { get { return syncRoot; } }

    ...
}

然后,你只需使用lock(o.SyncRoot) in DoSomething。这是一些 BCL 类使用的模式,例如,Array.SyncRoot http://msdn.microsoft.com/en-us/library/system.array.syncroot.aspx, ICollection.SyncRoot http://msdn.microsoft.com/en-us/library/system.collections.icollection.syncroot.aspx.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 锁定传递给方法的引用 - 不好的做法? 的相关文章

随机推荐