views:

125

answers:

3

I may be greatly misunderstanding this threading scenario, but that's why I'm asking.

What would/might happen in the following situation (assume C# threading)? Note: this scenario is simplified to the core issue, extra functionality is ignored.

I have 2 objects, a and b, which are instances of classes A and B respectively; 'b' is a member of 'a'.

'b' is running a processing loop and has a few other activities continually doing something. At one point, 'b' detects a situation which causes it to send an event to 'a'. When 'a' recieves this event, it executes the following code:

void b_eventFoo()
{
    b.UnhookEvents();//clears the delegate that truggered this event function
    this.b = new B();        
    b.HookEvents(this);//connects the new b object to this A
}

What happens to the old 'B' object? The original 'b' still is doing some processing and the very thread that triggered the event could still be executing. I don't understand threading well enough to predict the results of this scenario.

Does it even matter?

Please let me know if I should clarify anything.

+2  A: 

The original B is still running, you would just lose the reference to it.

Will Eddins
if it was the only reference to B, wouldn't it be deleted by garbage collector?
valya
@valya, only once the thread terminates - the thread handler maintains a reference, so A's reference wasn't the only one.
Dathan
valya: No, the thread's stack would also hold a reference to 'b', as `this` at least.
Henk Holterman
A: 

The old B is still running, and still has a reference to A. Since A is no longer aware of this B this is likely a very bad situation.

You should try to avoid circular references like this if at all possible, especially when an order of operations like this could happen. If A uses B and B uses A, why aren't they one class? They're fairly tightly coupled for them to both be accessing each other's members.

Donnie
B has a reference to A? Do you mean the event? That's disconnected before the reference A has to B is lost. I don't understand the problem you're seeing, please explain.
CodeFusionMobile
I've edited the OP to unhook the event as I do in the real application, I forgot to include this earlier. Only the new b has a reference to b_eventFoo
CodeFusionMobile
+2  A: 

At the start, you have:

Thread1: [A1] -----field ----> [B1]
              <--- event -----

You create a new thread, running a loop on B1; the key here is that delegates and instance methods (during use) themselves have a reference to the instance (it is "arg0" in IL terms); so you have:

Thread1: [A1] ---- field ----> [B1]
              <--- event -----   ^
Thread2: ------------------------^

You then unhook the event and cancel the field:

Thread1: [A1] ---- field ----> [nil]

Thread2: --------------------> [B1]

And recreate and rehook against a different instance:

Thread1: [A1] ---- field ----> [B2]
              <--- event -----

Thread2: --------------------> [B1]

So: your thread continues processing against [B1], but no longer impacts [A1]

Marc Gravell