multithreading 有没有办法检测物体是否被锁定?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1300199/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a way to detect if an object is locked?
提问by scope_creep
Is there any way to determine if an object is locked in C#? I have the unenviable position, through design where I'm reading from a queue inside a class, and I need to dump the contents into a collection in the class. But that collection is also read/write from an interface outside the class. So obviously there may be a case when the collection is being written to, as the same time I want to write to it.
有没有办法确定对象是否在 C# 中被锁定?我有一个令人羡慕的位置,通过设计我从类中的队列中读取,我需要将内容转储到类中的集合中。但该集合也是从类外的接口读/写。所以很明显,可能会出现正在写入集合的情况,因为我想同时写入它。
I could program round it, say using delegate but it would be ugly.
我可以围绕它进行编程,比如使用委托,但它会很丑陋。
采纳答案by casperOne
You can always call the static TryEnter
methodon the Monitor
classusing a value of 0 for the value to wait. If it is locked, then the call will return false.
您始终可以使用值 0 来调用类上的静态TryEnter
方法以等待值。如果它被锁定,则调用将返回 false。Monitor
However, the problem here is that you need to make sure that the list that you are trying to synchronize access to is being locked on itself in order to synchronize access.
但是,这里的问题是您需要确保您尝试同步访问的列表本身被锁定,以便同步访问。
It's generally bad practice to use the object that access is being synchronized as the object to lock on (exposing too much of the internal details of an object).
使用正在同步访问的对象作为要锁定的对象(暴露过多对象的内部细节)通常是不好的做法。
Remember, the lock could be on anything else, so just calling this on that list is pointless unless you are sure that list is what is being locked on.
请记住,锁可以在其他任何东西上,因此仅在该列表上调用它是没有意义的,除非您确定该列表是被锁定的。
回答by Barry Kelly
Monitor.TryEnter
will succeed if the object isn't locked, and will return false if at this very moment, the object is locked. However, note that there's an implicit race here: the instance this method returns, the object may not be locked any more.
Monitor.TryEnter
如果对象没有被锁定,将成功,如果此时对象被锁定,将返回 false。但是,请注意这里有一个隐含的竞争:此方法返回的实例,对象可能不再被锁定。
回答by Michael Bentley
I'm not sure if a static call to TryEnter with a time of 0 will guarantee that the lock will not be acquired if it is available. The solution I did to test in debug mode that the sync variable was locked was using the following:
我不确定以 0 时间对 TryEnter 的静态调用是否能保证在可用时不会获取锁。我在调试模式下测试同步变量被锁定的解决方案是使用以下内容:
#if DEBUG
// Make sure we're inside a lock of the SyncRoot by trying to lock it.
// If we're able to lock it, that means that it wasn't locked in the first
// place. Afterwards, we release the lock if we had obtained it.
bool acquired = false;
try
{
acquired = Monitor.TryEnter(SyncRoot);
}
finally
{
if (acquired)
{
Monitor.Exit(SyncRoot);
}
}
Debug.Assert(acquired == false, "The SyncRoot is not locked.");
#endif
回答by Aliaksei Kliuchnikau
Currently you may call Monitor.TryEnter to inspect whether object is locked or not.
目前你可以调用 Monitor.TryEnter 来检查对象是否被锁定。
In .NET 4.0 CLR team is going to add "Lock inspection API"
在 .NET 4.0 CLR 团队将添加“锁定检查 API”
Here is a quotation from Rick Byersarticle:
以下是Rick Byers文章的引述:
lock inspection
We're adding some simple APIs to ICorDebug which allow you to explore managed locks (Monitors). For example, if a thread is blocked waiting for a lock, you can find what other thread is currently holding the lock (and if there is a time-out).
锁检查
我们正在向 ICorDebug 添加一些简单的 API,它们允许您探索托管锁(监视器)。例如,如果一个线程被阻塞等待锁,您可以找到当前持有锁的其他线程(以及是否有超时)。
So, with this API you will be able to check:
1) What object is holding a lock?
2) Who's waiting for it?
因此,使用此 API,您将能够检查:
1) 持有锁的对象是什么?
2)谁在等它?
Hope this helps.
希望这可以帮助。
回答by user626528
Determines whether the current thread holds the lock on the specified object.
Available since 4.5
确定当前线程是否持有指定对象的锁。
自 4.5 起可用