是否有类似于 C# 中的锁的结构,可以跳过代码块而不是阻塞?
在我正在处理的代码段中,另一个开发人员的库定期、预定的时间间隔触发我的对象的方法之一。我遇到过这样的问题:在达到另一个时间间隔时,对我的对象方法的上一次调用尚未完成,并且对我的方法进行了第二次调用以再次执行 - 然后两个线程最终相互踩踏。我希望能够通过检查来包装该方法的实现,以查看它是否处于处理过程中,如果是,则跳过该块。
锁与我想要的类似,但并不能完全覆盖它,因为锁会阻塞,并且一旦前一个实例释放锁,对我的方法的调用就会立即开始。这不是我想要发生的情况,因为我可能最终会备份大量这些调用,并且全部等待一一处理。相反,我想要类似于锁的东西,但没有块,以便在通常被锁包围的代码块之后继续执行。
我想出了一个与 Interlocked.Increment 和 Interlocked.Decrement 一起使用的计数器,以允许我使用简单的 if 语句来确定是否应该继续执行该方法。
public class Processor
{
private long _numberOfThreadsRunning = 0;
public void PerformProcessing()
{
long currentThreadNumber Interlocked.Increment(ref _numberOfThreadsRunning);
if(currentThreadNumber == 1)
{
// Do something...
}
Interlocked.Decrement(ref _numberOfThreadsRunning);
}
}
我觉得我想得太多了,可能有一个更简单的解决方案。
In the piece of code that I'm working on, another developer's library fires off one of my object's methods on regular, scheduled intervals. I've run into problems where the previous call into my object's method has not completed at the time another interval is reached and a second call is made into my method to execute again - the two threads then end up stepping on each other. I'd like to be able to wrap the method's implementation with a check to see whether it is in the middle of processing and skip over the block if so.
A lock is similar to what I want, but doesn't quite cover it because a lock will block and the call into my method will pick up as soon as the previous instance releases the lock. That's not what I want to happen because I could potentially end up with a large number of these calls backed up and all waiting to process one by one. Instead, I'd like something similar to a lock, but without the block so that execution will continue after the block of code that would normally be surrounded by the lock.
What I came up with was a counter to be used with Interlocked.Increment and Interlocked.Decrement to allow me to use a simple if statement to determine whether execution on the method should continue.
public class Processor
{
private long _numberOfThreadsRunning = 0;
public void PerformProcessing()
{
long currentThreadNumber Interlocked.Increment(ref _numberOfThreadsRunning);
if(currentThreadNumber == 1)
{
// Do something...
}
Interlocked.Decrement(ref _numberOfThreadsRunning);
}
}
I feel like I'm overthinking this and there may be a simpler solution out there.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以调用
Monitor.TryEnter
并在返回 false 时继续。You could call
Monitor.TryEnter
and just continue if it returns false.向对象添加一个标志怎么样?在方法中设置标志 true 以指示该方法正在执行。在该方法的最后,将其重置为 false。然后你可以检查标志的状态来知道是否可以调用该方法。
How about adding a flag to the object. In the method set the flag true to indicated the method is being executed. At the very end of the method, reset it to false. Then you could check the status of the flag to know if the method can be called.