对象运行线程A被线程B销毁时会发生什么?

问题描述:

我可能会很大误解这种线程场景,但这就是为什么我问。对象运行线程A被线程B销毁时会发生什么?

以下情况会发生什么(假设C#线程)?注意:这种情况被简化为核心问题,额外的功能被忽略。

我有2个对象,a和b,它们分别是类A和类B的实例; 'b'是'a'的成员。

'b'正在运行一个处理循环,并且还有其他一些活动不断做某些事情。在某一时刻,'b'检测到导致它将事件发送到'a'的情况。当'a'接收到该事件时,它执行以下代码:

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 
} 

旧的'B'对象会发生什么?原来的'b'仍然在做一些处理,触发事件的线程仍然可以执行。我不太了解线程是否足以预测此场景的结果。

它甚至有问题吗?

请让我知道我是否应该澄清任何事情。

在开始时,您有:

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

您创建一个新的线程,运行在B1循环;这里的关键是代理和实例方法(使用期间)本身有一个对实例的引用(它是IL中的“arg0”);所以你必须:

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

你然后解开事件并取消场:

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

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

并重新创建,并针对不同的实例rehook:

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

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

所以:你的线程将继续处理反对[B1],但不再影响[A1]

原始B仍在运行,您只会失去对它的引用。

+1

如果它是对B的唯一引用,它不会被删除b y垃圾收集器? – 2009-11-24 19:15:40

+2

@valya,只有线程终止 - 线程处理程序维护一个引用,所以A的引用不是唯一的引用。 – Dathan 2009-11-24 19:17:45

+2

valya:不,线程的堆栈也会持有对'b'的引用,至少是'this'。 – 2009-11-24 19:21:06

旧的B仍在运行,仍然对A有参考。由于A不再知道这B这可能是一个非常糟糕的情况。

如果可能的话,你应该尽量避免这样的循环引用,特别是当这样的操作顺序可能发生时。如果A使用BB使用A,为什么他们不是一个类?他们非常紧密地联系起来,以便他们都可以访问彼此的成员。

+0

B有参考A?你的意思是这个事件吗?在参考文件A必须丢失B之前,这是断开的。我不明白你看到的问题,请解释一下。 – CodeFusionMobile 2009-11-24 19:31:27

+0

我已经编辑了OP来解开事件,就像我在真正的应用程序中做的那样,我忘了在之前加入这个事件。只有新的b有对b_eventFoo的引用 – CodeFusionMobile 2009-11-24 19:35:39