2009-11-24 87 views
1

我可能會很大誤解這種線程場景,但這就是爲什麼我問。對象運行線程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'仍然在做一些處理,觸發事件的線程仍然可以執行。我不太瞭解線程是否足以預測此場景的結果。

它甚至有問題嗎?

請讓我知道我是否應該澄清任何事情。

回答

2

在開始時,您有:

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]

2

原始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

0

舊的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

相關問題