很想知道是否有其他人看到过这个问题。我有一个锁定静态声明对象的应用程序,这样:
lock(Group.IsisGroups)
{
do some stuff
}
do-some-stuff 做了各种事情,我称之为尝试锁定同一个锁的例程之一。线程死锁。
我的猜测是,这个问题在某种程度上与我对反射的使用有关:在调用堆栈的中途,我通过在类定义中查找方法并调用 .Invoke() 来调用方法。结果的调用堆栈是这样的:
[In a sleep, wait, or join]
[External Code]
ConsoleApplication2.exe!Isis.Group.doLookup(Isis.Address gaddr) Line 3774 + 0x13 bytes
ConsoleApplication2.exe!Isis.ReliableSender.GotIncoming(byte type, Isis.Address gaddr, Isis.Address sender, int minStable, Isis.Msg m) Line 10179 + 0x9 bytes
ConsoleApplication2.exe!Isis.ReliableSender.doReceive.AnonymousMethod14(byte type, byte code, int seqn, int truePayLoadLen, int PreFragLen, Isis.Address sender, Isis.Address dest, Isis.Address gaddr, int minStable, int FID, int Fn, int nF, byte[] buf) Line 3120 + 0x80 bytes
[External Code]
ConsoleApplication2.exe!Isis.Msg.doInvokeSingle(System.Delegate del, byte[] barray, System.Type[] types) Line 11582 + 0x10 bytes
ConsoleApplication2.exe!Isis.Msg.InvokeFromBArray(byte[] barray, System.Delegate del) Line 11527 + 0xf bytes
ConsoleApplication2.exe!Isis.ReliableSender.doReceive(object os, Isis.Group g) Line 10034 + 0x71 bytes
ConsoleApplication2.exe!Isis.ReliableSender.Receive(Isis.Group g) Line 10013 + 0xe bytes
ConsoleApplication2.exe!Isis.ReliableSender.StartGroupReader.AnonymousMethod__6(object o) Line 9097 + 0xc bytes
[External Code]
因此,初始调用lock(Group.IsisGroups)
是在堆栈的顶部方法中,ReliableSender.StartGroupReader
当它在底部方法 doLookup 中调用 lock 时,代码会死锁。这些[External Code]
块来自我调用反射Invoke()
方法的地方,并且来自lock()
导致事情死锁的调用。绝对是同一个对象被锁定,等等(当我的类被加载并且是类型时静态分配的对象,List<Isis.Group>
当我添加和删除东西时,实际的 List 对象仍然存在。
关于可能导致这种情况的任何建议?