Help - Event registration is hanging

S

Sharon

Hello Gurus,

I have an event in a base class B.
Derived class D. And a class U that uses class D.

Class B has an event using Framework 2.0. I have tried to convert the event
and delegate from Framework 2 to the generics events of Framework 3.5, and
together with some other changes a bug has emerged:

The using class U try to register to the event by +=
The bug: The line that register with the += stuck and does not returns.
Note that the event registration in the UI thread.

I have changed back the event to the Framework 2 style, but the bug still
occur.
I couldn’t find any clue that can indicate what can cause this hanging.

Can anyone give any hint what may cause this event registration to hang?
 
J

Jeff Johnson

I have an event in a base class B.
Derived class D. And a class U that uses class D.

Class B has an event using Framework 2.0. I have tried to convert the
event
and delegate from Framework 2 to the generics events of Framework 3.5, and
together with some other changes a bug has emerged:

I don't have an answer for you, but I want to point out that 2.0 introduced
the generic EventHandler<argsType> syntax, not 3.5. "Event-and-delegate" was
a 1.x thing (not to suggest it stopped working in 2.0).
 
P

Peter Duniho

Sharon said:
[...]
The using class U try to register to the event by +=
The bug: The line that register with the += stuck and does not returns.
Note that the event registration in the UI thread.

I have changed back the event to the Framework 2 style, but the bug still occur.
I couldn’t find any clue that can indicate what can cause this hanging.

Can anyone give any hint what may cause this event registration to hang?

The hint: you have an explicitly-implemented event and have either an
infinite loop in the implementation, or deadlock.

For more information than that, you need to post a concise-but-complete
code example that reliably demonstrates the problem.

Pete
 
S

Sharon

Hi again,
I found the problem and it not really in the event;

The event in of class A. Before registering to its event, class A was in a
lock(this) of thread b, where this is the pointer of class A.
So whenever any someone in other thread was trying to register to the event
of class A by +=, it was blocked!

After I changed the locking mechanism and also changed the locking key from
this to another object, the problem was solved.


But now I have a question about it:

Does the event registration by += is locking the this pointer of the
containing class?


--
Thanks
Sharon


Peter Duniho said:
Sharon said:
[...]
The using class U try to register to the event by +=
The bug: The line that register with the += stuck and does not returns.
Note that the event registration in the UI thread.

I have changed back the event to the Framework 2 style, but the bug still occur.
I couldn’t find any clue that can indicate what can cause this hanging.

Can anyone give any hint what may cause this event registration to hang?

The hint: you have an explicitly-implemented event and have either an
infinite loop in the implementation, or deadlock.

For more information than that, you need to post a concise-but-complete
code example that reliably demonstrates the problem.

Pete
 
P

Peter Duniho

Sharon said:
Hi again,
I found the problem and it not really in the event;

Well, based on your description, that's not entirely true. After all,
you said the code hung on the program statement subscribing to the
event. So obviously at least part of the problem was in the event, even
if it wasn't necessary to modify the event implementation to fix the
problem.
The event in of class A. Before registering to its event, class A was in a
lock(this) of thread b, where this is the pointer of class A.
So whenever any someone in other thread was trying to register to the event
of class A by +=, it was blocked!

A deadlock requires two or more synchronization objects. In addition to
everything you've described, there must have been a second lock also
taken, as well as a dependency between the two pieces of code that had
already acquired each lock (i.e. each waiting on each other, either
directly or indirectly).

If the only lock that had been acquired was that of the instance of
"class A", then the other thread trying to subscribe to the event would
simply have been delayed momentarily, not blocked indefinitely (i.e.
"hanging", as your subject text says).

So, the code that had acquired the lock on the instance of class A must
also have been waiting for some other code in a _different_ thread, via
some mechanism (e.g. a lock on a different synchronization object),
where that different thread was trying to perform the event
subscription, or was otherwise itself waiting on the thread with the
lock on the instance of A.

Note that the Control.Invoke() method is one relatively common way for
code to have a synchronization dependency that is not obvious to the
casual observer.

Of course, without a code example, it's not possible to say for sure the
exact nature of the deadlock. But deadlock does require two or more
locks (where "lock" is simply any mechanism in which one thread has to
wait on another...not necessarily the "lock" statement itself).
After I changed the locking mechanism and also changed the locking key from
this to another object, the problem was solved.

But now I have a question about it:

Does the event registration by += is locking the this pointer of the
containing class?

By default, yes.

Your own synchronization code should not use "this" for locking anyway.
Even ignoring event implementation, it's a hazardous approach to
locking, because your code is locking on a reference that is publicly
available, and thus for which it has no control over what other code may
be using it for locking.

And in fact, the default implementation for events in C# is to use
"this" for locking during the event's add and remove methods. This
would be a good example of exactly the hazard I describe above.

Pete
 
S

Sharon

Hi again,

Well, it goes like this;
Thread b was locking the this of class A forever (bug that was fixed). No
other thread was trying or locking the this of class A.
Whenever a user of the class A event was trying to register to this event
(in another thread, e.g. thread c), was hanging forever because the this was
locked by thread b forever!

I fixed the problem and it’s working fine now.

I’m wondering about the event:
Does the event registration by += is locking the this pointer of the
containing class?
I didn’t find any documentation saying that, but I have a feeling that the
event registration does lock the this of the containing class. Am I right?
 
P

Peter Duniho

Sharon said:
Hi again,

Well, it goes like this;
Thread b was locking the this of class A forever (bug that was fixed). No
other thread was trying or locking the this of class A.

Thread B should not have been locking on the instance of A, but given
that it was, it only blocked the event subscription because of the
implementation of the event's add method in A. That's my point. You
may not have needed to change the event's add method, but it's at least
partly responsible, because it's that specific implementation of the
event's add method that was resulted in a problem.
[...]
I’m wondering about the event:
Does the event registration by += is locking the this pointer of the
containing class?

I answered that question already. Did you read my entire reply?
I didn’t find any documentation saying that, but I have a feeling that the
event registration does lock the this of the containing class. Am I right?

See above.

As for documentation, I didn't find it with a quick search on MSDN, but
I know that MSDN does document the default implementation for events.

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top