C#可以锁定方法参数吗?

时间:2010-04-28 14:53:56

标签: c# multithreading

我们在类中有一个类变量ArrayList binaryScanData。在有权访问它的所有方法中,我们将lock(binaryScanData)放在它上面,因为它是共享的。现在我们要将其中一个方法移到另一个util类中,使其成为static方法。我们会将binaryScanData传递给这样的方法:

public static void convertAndSaveRawData(ref MemoryStream output, ref ArrayList binaryScanData)

我们的问题如下:

  1. 我们怎样才能使binaryScanData符号化?我们可以像原来那样做吗?
  2. ref是必要的吗?它只会在convertAndSaveRawData方法中阅读。

6 个答案:

答案 0 :(得分:4)

ref不是必需的,只有在您要更改引用本身时才需要它(即,为其指定一个新列表)。如果愿意,您仍然可以锁定对象。我建议锁定SyncRoot,我不确定ArrayList是否有。如果没有,您可以考虑升级到List<T>

答案 1 :(得分:4)

除非您撰写ref,否则无需将其设为binaryScanData = something参数。

您可以像锁定其他任何内容一样锁定参数 C#lock keyowrd锁定对象实例;实例的来源并不重要。

答案 2 :(得分:2)

这听起来非常错误。我可以想象你的类对象共享一个ArrayList实例,因此需要同步访问它的代码。但这会使ArrayList对象引用为静态,为什么你必须将它作为参数传递?

如果其他代码需要调用此静态方法而不必使用对类对象的引用,那么他们可能必须传递自己的ArrayList实例。那么你不再需要锁定就没有意义了。调用代码需要处理锁定。只有它知道在其他地方使用特定的ArrayList对象。

抱歉,我无法理解它。首先,您使用ArrayList对象作为lock参数。您无法锁定数据,只能锁定使用数据的代码。

答案 3 :(得分:1)

  
      
  1. 我们如何sychoronize binaryScanData?我们可以像原来那样做吗?
  2.   

通过从需要同步的每段代码中锁定相同的对象实例。

请注意,这并不一定意味着锁定您正在修改的同一个对象。事实上,这是危险的,被认为是不好的做法。它使您容易受到死锁和其他恶意的影响,因为其他一些代码可能会锁定同一个对象。您最好创建自己的私有对象并将其用于同步。

  
      
  1. ref是必要的吗?它只会在convertAndSaveRawData方法中读取。
  2.   

不,不是。你有两个截然不同的概念。

答案 4 :(得分:0)

您可以为现有ArrayList创建一个同步包装器,该包装器内部锁定所有get / sets:

ArrayList unsyncList = new ArrayList();
ArrayList syncWrapperList = ArrayList.Synchronized(unsyncList);

锁定有一个性能成本,因此只能使用必须同步每个调用的包装器。

答案 5 :(得分:0)

任何参数都不需要

ref,因为它们都是引用传递,因为它们是引用类型。

正如已经指出的那样,ArrayList不再被推荐为持有物品清单的方式,因为它通常需要装箱,因此通常要慢得多。除非您使用的是1.1

,否则请尝试使用List<T>

这两点不能回答你的主要问题:同步列表并不是一项简单的任务,因为.NET实现不是线程安全的。您可以看到关于它的整个讨论: Why is C# List<> not thread-safe? 您可以在自己的类中同步列表,但它仍然可以在该类之外进行更改。

如果您自己创建了列表,则有一种方法是将其设为read-only list,并提供通过子类化List<T>IList<T>添加到其中的方法。

这篇ThreadSafe List文章尝试制作一个通用的线程安全列表,但如果您阅读页面底部的注释,它仍然有缺点。