在.NET 3.5中提供有关状态的信息的锁定机制
-
29-09-2019 - |
题
我正在尝试找到一种提供对资源的独家访问的方法,同时提供有关锁状态(_isworking)的信息,以供其他类读取。
这是我到目前为止提出的:
private int _isWorking = 0;
public bool IsWorking
{
get { return Interlocked.CompareExchange(ref _isWorking, 0, 0) == 1; }
}
public void LaunchProcess()
{
if (Interlocked.CompareExchange(ref _isWorking, 1, 0) == 0)
{
try
{
DoExpansiveProcess();
}
finally
{
Interlocked.Exchange(ref _isWorking, 0);
}
}
}
public void DoExpansiveProcess()
{
Thread.Sleep(30000);
}
它不能完全用作锁定,因为第二个线程看到线程已经运行该过程后,只会离开该方法而无需做任何事情即可。
是正确的方法还是有其他C#3.5结构为此目的进行改编?
以及如何实现“真实”锁定方案,在第一个线程完成后,第二个线程仍将执行该方法,同时提供有关状态的信息?
解决方案
假设我正确理解了您的问题,那么我认为您是什么 Monitor.TryEnter
超时值为0的方法将尝试获取锁定,但是暂停为0,它将始终立即返回,值表示锁定是否实际获取。这里的暗示是,如果未获得锁,则假定它已经被其他人获取。问题是如果返回 true
然后,您必须立即通过打电话发布 Monitor.Exit
.
也许这将是一个更好的解决方案:
public class Worker
{
private Object m_LockObject = new Object();
private volatile bool m_IsWorking = false;
public bool IsWorking
{
get { return m_IsWorking; }
}
public void LaunchProcess()
{
lock (m_LockObject)
{
m_IsWorking = true;
DoExpansiveProcess();
m_IsWorking = false;
}
}
}
其他提示
System.Threading.ManualResetEvent
也许可以在这里提供帮助。只需对此做一个waitone()。如果使用它,它将返回为false。如果不使用它,则可以使用。
WaitOne()超载之一需要花费一些时间才能等待。如果您使用Waitone(0),则等待将立即以非阻止方式返回。
您应该对.NET提供的同步基元进行一些研究:
System.Threading.Monitor lock() { }
System.Threading.ManualResetEvent
System.Threading.AutoResetEvent
System.Threading.Semaphore
System.Threading.Mutex
我认为您的方法一般应该是正确的,并且肯定会比使用ManualResetevent(如果它完全相关)要快得多 - 因为手动Resetevent包裹了无管理的原始原始内容。
但是,为了使这种方法安全,必须是私人的。
不隶属于 StackOverflow