我可以确定这个临时变量不会被优化掉吗?
我的系统中工作线程上发生了一些事情。假设状态发生了变化。我想在 UI 线程中处理新的 state,因此我调度一个要在那里调用的委托:
var state = GetState();
Dispatcher.BeginInvoke(() => StateChanged(state));
当 StateChanged
在 UI 线程上执行时,我可以确定参数state
的值是GetState()
在调度之前返回的值,或者是临时的state
变量被优化,以便 GetState()
在 UI 线程上调用来填充 StateChanged
参数?
Something happens in my system on a worker thread. Let's say that the state changes. I want to handle the new state in the UI thread, so I dispatch a delegate to be invoked there:
var state = GetState();
Dispatcher.BeginInvoke(() => StateChanged(state));
When StateChanged
executes on the UI thread, can I then be sure that the value of the parameter state
is the value returned by GetState()
before the dispatch, or will the temporary state
variable be optimized away so that GetState()
is called on the UI thread to populate the StateChanged
parameter?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
不,
GetState
肯定会在工作线程上调用。在 lambda 表达式中移动GetState()
调用的“优化”将完全无效。No,
GetState
will definitely be called on the worker thread. An "optimization" to move theGetState()
call within the lambda expression would be entirely invalid.这不会发生,因为它会改变操作的语义,优化不允许这样做;您通过调用方法对变量进行赋值,因此由于 C# 不是惰性语言,因此此时必须发生这种情况。
This will not happen as it would change the semantics of the operations, optimizations are not allowed to do that; you make an assignment to a variable by calling a method, so because C# is not a lazy language this will have to happen at that point.
你的代码
没问题。但这种变化将更难以分析和证明其正确性:
Your code
is fine. But this variation would be much more difficult to analyze and prove correct:
状态
不会被优化掉。然而,之前实际上是这个问题的棘手部分。只要您之后(在同一范围内)不更改状态变量,您就无需担心。
在上面的代码中,
state
不会被优化掉。但是,这并不意味着StateChanged
将以值 2 进行调用。如果工作线程在启动调度程序线程之前完成执行,则可能是 3。这里的要点是变量捕获确保保留该值以供闭包使用,但这并不意味着该值是不可变的。
No
state
won't be optimized away.However, Before is actually the tricky part about this question. As long as you are not changing the state variable after (in the same scope) you have nothing to worry about.
In the code above
state
won't be optimized away. It does not mean, however, thatStateChanged
will be invoked with value 2. It could be 3, if the worker thread completes execution before starting the dispatcher thread.The main point here is that variable capturing insures that the value is preserved for the use of the closure, but that does not mean that the value is immutable.