2009-11-24 6 views
1

Возможно, я очень недопонимаю этот сценарий, но именно поэтому я спрашиваю.Что происходит, когда объект, выполняющий поток A, уничтожается нитью B?

Что могло бы произойти в следующей ситуации (предположим, что C# Threading)? Примечание: этот сценарий упрощен для основной проблемы, дополнительные функции игнорируются.

У меня есть 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' все еще выполняет некоторую обработку, и сам поток, который вызвал событие, все еще может выполняться. Я не понимаю потоки достаточно хорошо, чтобы предсказать результаты этого сценария.

Это даже имеет значение?

Пожалуйста, дайте мне знать, если я что-нибудь разъясню.

ответ

2

В начале, у вас есть:

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

Вы создаете новую тему, работает петлю на В1; Ключевым моментом здесь является то, что методы делегатов и экземпляров (во время использования) сами имеют ссылку на экземпляр (это «arg0» в терминах IL); поэтому у вас есть:

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

Вы потом отцепить событие и отменить поле:

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

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

И воссоздать и rehook против другого экземпляра:

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

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

Итак: ваш поток продолжает обработку против [B1], но больше не воздействует на [A1]

2

Оригинальный B все еще работает, вы просто потеряете ссылку на него.

+1

, если это была единственная ссылка на B, не будет ли она удалена мусором co llector? –

+2

@valya, только после прекращения потока - обработчик потока поддерживает ссылку, поэтому ссылка A была не единственной. – Dathan

+2

valya: Нет, стек потока также будет содержать ссылку на 'b', как минимум на 'this'. –

0

Старая B все еще работает и по-прежнему имеет ссылку на A. Поскольку A больше не знает об этом B, это, вероятно, очень плохая ситуация.

Вам следует стараться избегать циркулярных ссылок, подобных этому, если это вообще возможно, особенно если такой порядок действий может произойти. Если A использует B и B использует A, почему бы им не выбрать один класс? Они достаточно тесно связаны для того, чтобы они оба получали доступ к членам друг друга.

+0

B имеет ссылку на A? Вы имеете в виду событие? Это отключено до того, как ссылка A будет потеряна. Я не понимаю проблему, которую вы видите, поясните. – CodeFusionMobile

+0

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