我可以确定这个临时变量不会被优化掉吗?

时间:2012-02-13 23:48:30

标签: c# wpf silverlight optimization dispatcher

我的系统在工作线程上发生了一些事情。假设状态发生变化。我想在UI线程中处理新的状态,所以我派遣一个委托在那里调用:

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

在UI线程上执行StateChanged时,我是否可以确保参数state的值是GetState() 返回的值之前dispatch,或者是否会优化临时state变量,以便在UI线程上调用GetState()来填充StateChanged参数?

4 个答案:

答案 0 :(得分:4)

不,肯定会在工作线程上调用GetStateGetState()调用的“优化”完全无效。

答案 1 :(得分:2)

这不会发生,因为它会改变操作的语义,不允许进行优化;你通过调用一个方法对一个变量赋值,所以因为C#不是一个惰性语言,所以 必须在那个时候发生。

答案 2 :(得分:2)

您的代码

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

很好。但是这种变化将难以分析并证明是正确的:

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

答案 3 :(得分:1)

  

然后我可以确定参数状态的值是值   在调度之前由GetState()返回>或者将优化临时状态变量>远

不会优化state。 但是,之前实际上是关于这个问题的棘手部分。只要您不在之后更改状态变量(在同一范围内),您就无需担心。

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

在上面的代码中state将不会被优化掉。但是,这并不意味着将使用值2调用StateChanged。如果工作线程在启动调度程序线程之前完成执行,则它可以是3。

这里的要点是变量捕获确保了为闭包的使用保留了值,但这并不意味着值是不可变的。