2010-04-28 41 views
3

我们在一个类中有一个类变量ArrayList binaryScanData。在有权访问的所有方法中,我们将lock(binaryScanData)放在它上面,因为它是共享的。现在我们要将这些方法之一移出到另一个util类,以使其成为static方法。我们将传递到binaryScanData像这样的方法:C#可以锁定一个方法参数吗?

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

我们的问题是如下:

  1. 怎能sychoronize是binaryScanData?我们可以像原来一样吗?
  2. ref是必要的吗?它只会在convertAndSaveRawData方法中读取。
+0

考虑改变你的实现 - 如果你传回void和使用多个ref参数,你应该考虑做一个响应对象。 – Tejs 2010-04-28 14:56:47

+3

为什么要使用ArrayList而不是泛型等价物,如List ? – 2010-04-28 14:58:39

回答

4

该ref不是必需的,只有在您要更改引用本身(即为其分配新列表)时才需要。如果你喜欢,你仍然可以锁定对象。我建议锁定SyncRoot,我不确定ArrayList是否有。如果不是,您可能会考虑移动到List<T>

+0

如果我锁定方法参数,它是否也锁定传入的原始对象? – 5YrsLaterDBA 2010-04-28 15:29:34

+0

某些人不鼓励使用SyncRoot ... http://blogs.msdn.com/brada/archive/2003/09/28/50391.aspx – kervin 2010-04-28 15:29:54

4

除非您编写binaryScanData = something,否则不需要将其设置为ref参数。

您可以锁定参数,就像锁定其他任何东西一样。
C#lock keyowrd锁定对象实例;这个实例来自何处并不重要。

+2

记住你不需要锁定是很重要和有用的您要锁定的对象。您可以锁定来自System.Object的任何内容。例如,您可以拥有一个ListOfPeople,并在使用它时锁定一个完全不相关的对象,例如PeopleLockObject。提供访问ListOfPeople的每一次尝试都会在PeopleLockObject上执行锁定,这并不重要。记住这一点很重要,因为锁定对象不会对对象做任何事情。这也意味着如果你锁定了一个对象,你仍然可以从另一个线程访问它并在两个地方都不使用锁 – NibblyPig 2010-04-28 16:10:38

1
  1. 我们该如何协调这个binaryScanData?我们可以像原来一样吗?

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

请注意,这并不一定意味着锁定与您要修改的对象相同。事实上,这是危险的,被认为是不好的做法。它会让你容易受到死锁和其他问题的困扰,因为其他代码可能会锁定同一个对象。您最好创建自己的私有对象并将其用于同步。

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

不,不是。你有两个完全不同的概念混在一起。

0

您可以创建一个同步包装到一个现有的ArrayList上的所有内部锁定获取/套:

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

有一个PERF成本锁定,所以只能使用包装,你必须同步每个呼叫。

2

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

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

对不起,我无法理解它。这从你使用ArrayList对象作为锁定参数开始。您无法锁定数据,只能锁定使用数据的代码。

0

ref对于任一参数都不需要,因为它们都是引用传递的,因为它们都是引用类型。

正如已经指出的那样,ArrayList不推荐作为持有物品清单的方式,因为它通常需要装箱,因此通常会慢很多。尝试List<T>,除非你正在使用1.1

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

一种技术,如果您自己创建了列表,则可以将其设置为read-only list,并通过继承List<T>IList<T>来提供添加方法。

ThreadSafe List文章试图做一个通用的线程安全列表,但如果您阅读页面底部的评论它仍然存在缺陷。

相关问题