3 回答
TA贡献1836条经验 获得超3个赞
你可以使用锁:)
object locker = new object();
void MethodToLockForAThread()
{
lock(locker)
{
//put method body here
}
}
现在的结果是,当这个方法被一个线程(任何线程)调用时,它会在锁的开头放置类似标志的东西:“停止!你不能再进一步了,你必须等待!” 就像十字路口的红灯。当首先调用此方法的线程离开作用域时,然后在作用域的开头,这个“红灯”变为绿色。
如果您不想在该方法已被另一个线程调用时调用该方法,唯一的方法是使用 bool 值。例如:
object locker = new object();
bool canAccess = true;
void MethodToLockForAThread()
{
if(!canAccess)
return;
lock(locker)
{
if(!canAccess)
return;
canAccess = false;
//put method body here
canAccess = true;
}
}
锁定范围内对 canAccess 的其他检查是因为评论中的内容。不,它真的是线程安全的。这是一种在线程安全单例中可见的保护。
编辑
在与 mjwills 讨论后,我必须改变主意,将更多内容转变为 Monitor.TryEnter。你可以这样使用它:
object locker = new object();
void ThreadMethod()
{
if(Monitor.TryEnter(locker, TimeSpan.FromMiliseconds(1))
{
try
{
//do the thread code
}
finally
{
Monitor.Exit(locker);
}
} else
return; //means that the lock has not been aquired
}
现在,由于某些异常或其他线程已经获取了锁,因此无法获取锁。在第二个参数中,您可以传递线程等待获取锁的时间。我在这里给了很短的时间,因为你不希望其他线程在第一次做的时候做这项工作。所以这个解决方案似乎是最好的。
当另一个线程无法获得锁时,它会走得更远而不是等待(它会等待1毫秒)。
TA贡献1779条经验 获得超6个赞
由于lock是围绕类的特定于语言的包装器Monitor,因此您需要Monitor.TryEnter:
public class SomeService
{
private readonly object lockObject = new object();
public void StartSomeMethod()
{
if (Monitor.TryEnter(lockObject))
{
// start new thread
}
}
public void SomeMethod()
{
try
{
// ...
}
finally
{
Monitor.Exit(lockObject);
}
}
}
TA贡献1817条经验 获得超6个赞
您可以使用 aAutoResetEvent代替您的isLocked标志。
AutoResetEvent autoResetEvent = new AutoResetEvent(true);
public void StartSomeMethod()
{
if(autoResetEvent.WaitOne(0))
{
//start thread
}
}
public void SomeMethod()
{
try
{
//Do your work
}
finally
{
autoResetEvent.Set();
}
}
- 3 回答
- 0 关注
- 100 浏览
添加回答
举报