C # попытка повторной блокировки чего-то заблокированного, очевидная ошибка - PullRequest
0 голосов
/ 24 января 2011

Любопытно узнать, видел ли кто-нибудь еще эту проблему.У меня есть приложение, которое блокирует статически объявленный объект, следующим образом:

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.,Блоки [External Code] находятся там, где я вызвал метод отражения Invoke(), и из вызова в lock(), что привело к тупиковой ситуации.Определенно, тот же объект заблокирован и т. Д. (Объект статически размещается, когда мой класс загружен и имеет тип List<Isis.Group>, и хотя я действительно добавляю и удаляю объекты, фактический объект List остается в порядке.

Все предложенияна что это может быть причиной?

Ответы [ 2 ]

1 голос
/ 24 января 2011

Я правильно читаю?

Таким образом, первоначальный вызов lock (Group.IsisGroups) находится в верхнем методе стека [...], а код блокируется при вызове блокировки нижнего метода [...] в lock (), что вызвало вещи в тупик. Определенно, один и тот же объект заблокирован.

Какой-то псевдокод ваших методов, который показывает, как они блокируют, помог бы, но на основании того, что я прочитал, звучит так, как будто вы блокируете один и тот же объект с помощью блокировки?

Если Я правильно прочитал, похоже, что это произошло

lock(ob1)
{
  lock(ob1)
  {
  }
}

но ты выглядишь совершенно уверенным в себе, так что я предполагаю, что неправильно это прочитал.

в любом случае, неплохо было бы использовать псевдокод методов, вызывающих блокировки. : Р

Взаимные блокировки вызваны несколькими методами / потоками, блокирующими объекты в «неправильном» порядке.

0 голосов
/ 26 января 2011

ОК, не хочется оставлять это открытым, поэтому мой «ответ» таков: во-первых, (извините) Бенги и Ханс, похоже, просто не понимают этого достаточно точно, блокировка повторного входа работает неправильно.Во-вторых, я подозреваю, что это происходит из-за моего использования отражения;каким-то образом контекстная информация, которую они используют, чтобы понять, что блокировка повторно блокируется тем же потоком, по-видимому, подвергается воздействию.

Я собираюсь исправить это, изменив свой код, чтобы он не удерживал блокировку во время начальнойвызов;по сути, я не буду пытаться получить эту блокировку повторно.

Остальные, кто сталкивается с этим потоком, должны быть предупреждены: насколько я могу судить, я сталкиваюсь с тем, что может быть только ошибкой .NET.И это не очень сложно спровоцировать.

...