2012-02-13 42 views
0

我的系統在工作線程中發生了一些事情。假設狀態發生變化。我想處理在UI線程的新狀態,所以我派代表到那裏調用:我可以確定這個臨時變量不會被優化掉嗎?

var state = GetState(); 
Dispatcher.BeginInvoke(() => StateChanged(state)); 

StateChanged執行UI線程,可我當時肯定的是,參數的值stateGetState()之前發送的值,還是會暫時將state變量優化掉,以致在UI線程上調用GetState()來填充StateChanged參數?

+2

歡迎來到_closures_的美好世界。這很好。 – SLaks 2012-02-13 23:52:26

回答

1

可我當時肯定的是,參數狀態的值是調度或之前GETSTATE()返回的值 將臨時狀態變量優化>消失

state不會被優化掉。 但是,之前實際上是關於這個問題的棘手部分。只要你沒有在之後改變狀態變量(在相同的範圍內),你完全沒有必要擔心。

{ 
// say GetState returns 2 
var state = GetState(); 
// state now = 2 
Dispatcher.BeginInvoke(() => StateChanged(state)); 
state = 3; 
} 

在上面的代碼state不會被優化掉。但是,這並不意味着StateChanged將被調用值2.如果工作線程在啓動調度程序線程之前完成執行,則它可能爲3。

這裏的主要觀點是,變量捕獲確保該值保留用於閉包的使用,但這並不意味着該值是不可變的。

4

不,GetState肯定會在工作線程上調用。在lambda表達式中調用GetState()調用的「優化」將完全無效。

2

這不會發生,因爲它會改變操作的語義,不允許優化;你通過調用一個方法來給一個變量賦值,因爲C#不是一種懶惰的語言,所以這個必須在那個時候發生

2

您的代碼

var state = GetState(); 
Dispatcher.BeginInvoke(() => StateChanged(state)); 

是罰款。但是,這種變化將更加難以分析和證明正確的:

var state = GetState(); 
Dispatcher.BeginInvoke(() => StateChanged(state)); // after GetState() 
state = null;      // before or after StateChanged() ? 
+0

這種變化實際上很容易證明錯誤。 – SLaks 2012-02-14 00:13:40

+0

@SLaks:請詳細說明...... – 2012-02-14 07:26:10

+0

Slaks是正確的 - 此代碼StateChanged將總是看到'state == null'。我正在考慮一個線程。 – 2012-02-14 08:39:34