我的系统在工作线程上发生了一些事情。假设状态发生变化。我想在UI线程中处理新的状态,所以我派遣一个委托在那里调用:
var state = GetState();
Dispatcher.BeginInvoke(() => StateChanged(state));
在UI线程上执行StateChanged
时,我是否可以确保参数state
的值是GetState()
返回的值之前dispatch,或者是否会优化临时state
变量,以便在UI线程上调用GetState()
来填充StateChanged
参数?
答案 0 :(得分:4)
不,肯定会在工作线程上调用GetState
。 1}}在lambda表达式中移动GetState()
调用的“优化”完全无效。
答案 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。
这里的要点是变量捕获确保了为闭包的使用保留了值,但这并不意味着值是不可变的。