【发布时间】:2014-02-26 00:07:15
【问题描述】:
我有一个在任意数量的线程中实例化的类,这些线程根据需要进行假脱机。这意味着在任何时候都可以使用该类的任意数量的实例化版本,并且该类的一部分需要锁定以防止并发访问。
为了防止各个线程之间出现数据问题,我需要一种方法来锁定一段代码,使其与其他线程中的其他实例化版本的类不兼容。由于这个类可以有多个实例化版本,我不能只使用私有成员变量来锁定(而且我知道不要使用 Type 或任何可公开访问的东西);所以我使用了一个私有静态成员变量。
这是解决这个问题的合理方法吗?还是有更好的解决方案?
示例代码如下:
public class MyClass
{
private static object LockingVar = new object();
public void MyPublicMethod()
{
lock (LockingVar)
{
// Do some critical code
}
}
编辑
MyPublicMethod 正在调用本地 SQLExpress 实例,除了更新和插入之外,它还可以执行选择,因此它需要在另一个线程进入并将其搞砸之前完成。
【问题讨论】:
-
1) 您锁定共享资源以防止损坏,2) 如果共享资源是基于实例的[即多个线程访问单个类实例],您的
LockingVar[通常称为 SyncRoot] 应该是基于实例的'private readonly object LockingVar', 3) 如果共享资源是基于静态的[即许多实例,每个线程一个,每个实例引用一个静态列表],那么您的锁也应该是静态的。 fwiw,我会避免任何静态的东西,但我们必须做我们必须做的:) -
鉴于您的编辑 - 您不能依靠数据库事务来确保并发选择/插入/更新不会相互破坏,而不是在调用代码中使用相当残酷的锁定吗?跨度>
-
我会这么认为,只是它不只是进行数据库调用。它还在对关键/共享数据进行更改。这会改变现状吗?在这一点上,我意识到我本可以提供有关我的确切解决方案的更多详细信息。
-
-
根据这里 (docs.microsoft.com/en-us/dotnet/csharp/language-reference/…) :最佳做法是定义一个私有对象来锁定,或者定义一个私有静态对象变量来保护所有实例共有的数据。