2014-03-31 37 views
2

將其中一個嵌套在其他內部嗎?在過去,我有一個掛起/死鎖問題,我可以在做代碼的頂層代碼塊時重現,當我將其更改爲底部代碼塊時,我無法重現......我真的不明白它在時間,而我仍然沒有。我應該知道關於鎖的& InvokeOnMainThread的組合嗎?我公司可提供約我在做什麼更多的細節,但是這是比任何事情的一般問題...在鎖內嵌套InvokeOnMainThread,或者反之亦然

比方說,我想「DoStuff」在後臺線程。我有一個從多個線程訪問的變量。

lock(stuff) 
{ 
    InvokeOnMainThread (delegate { 
     stuff.DoStuff(); 
    }); 
} 

備用

InvokeOnMainThread (delegate { 
    lock(stuff) 
    { 
     stuff.DoStuff(); 
    } 
}); 

新增信息:我有在後臺線程運行的連接管理器功能,iOS應用程序。連接管理器功能負責保持活動並管理異步網絡套接字連接。有很多情況下,我需要InvokeOnMainThread當做事情,否則我會得到以下錯誤「UIKit一致性錯誤:您正在調用UIKit方法,只能從UI線程調用。」

+0

,如果你在後臺線程想DoStuff(),爲什麼你運行它在主線程上? – Jason

+0

我試圖簡化一個潛在的複雜問題......也許這使得這個問題變得無法回答。看到上面添加的內容 – LampShade

回答

1

兩者之間的區別是,代碼第二塊不會阻止任何來自您DoStuff之前執行的線程上執行。

實施例:

lock (stuff) { 
    InvokeOnMainThread (delegate { Console.WriteLine ("a"); } } 
} 
Console.WriteLine ("b"); 

將打印:

a 
b 

而此代碼:

InvokeOnMainThread (delegate { 
    lock (stuff) { 
     Console.WriteLine ("a"); 
    } 
} 
Console.WriteLine ("b"); 

通常會(但不一定)打印:

b 
a 

現在,這並不能解釋爲什麼第二塊會操縱比賽的條件,但我的猜測是,它只是改變了比賽的條件足以讓你不再打它(所以不是修復它,只是隱藏) 。

0

因此,如果我們假設這是隻有在你使用的鎖(的東西),唯一合乎邏輯的解釋方法爲什麼是第一種情況導致你僵局線程A(背景THEAD)談到這個方法裏面去鎖(東東) 。所以現在東西被鎖定在線程A上。現在線程A調用MainThread,如果你從stuff.DoStuff()調用這個方法,你會得到死鎖,因爲MainThread會運行到鎖(東西),它會等到線程A釋放鎖),但當MainThread調用完成時,線程A將釋放......導致死鎖。

即使你沒有從stuff.DoStuff()從MainThread的任何地方調用此方法發生死鎖,也有第一種情況發生的可能性唯一的區別是InvokeOnMainThread不執行stuff.DoStuff()但它只是排隊在MainThread上執行導致相同的死鎖情況。

現在第二個例子中,lock(stuff)在InvokeOnMainThread中,所以不會發生死鎖,因爲lock(stuff)只是在MainThread上做的,所以它沒有任何功能,所以你可以刪除它。因爲在MainThread上執行代碼已經100%同步「鎖定」了。

相關問題