Могу ли я быть уверен, что эта временная переменная не будет оптимизирована? - PullRequest
0 голосов
/ 14 февраля 2012

Что-то происходит в моей системе в рабочем потоке.Допустим, что состояние изменяется.Я хочу обработать новое состояние в потоке пользовательского интерфейса, поэтому я отправляю делегата, который будет там вызываться:

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

Когда StateChanged выполняется в потоке пользовательского интерфейса, могу ли яубедитесь, что значение параметра state является значением, возвращаемым GetState() перед отправкой , или будет оптимизирована временная переменная state, чтобы в пользовательском интерфейсе вызывался GetState()поток для заполнения параметра StateChanged?

Ответы [ 4 ]

4 голосов
/ 14 февраля 2012

Нет, GetState обязательно будет вызван в рабочем потоке.«Оптимизация» для перемещения вызова GetState() в лямбда-выражении была бы совершенно недействительной.

2 голосов
/ 14 февраля 2012

Ваш код

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

в порядке. Но этот вариант будет гораздо сложнее проанализировать и доказать правильность:

var state = GetState();
Dispatcher.BeginInvoke(() => StateChanged(state));  // after GetState()
state = null;                       // before or after StateChanged() ?
2 голосов
/ 14 февраля 2012

Этого не произойдет, так как это изменит семантику операций, оптимизация не может этого сделать; Вы делаете присвоение переменной, вызывая метод, поэтому, поскольку C # не является ленивым языком, в этом месте должно произойти .

1 голос
/ 14 февраля 2012

могу ли я тогда быть уверен, что значение параметра состояния является значением возвращается GetState () до отправки или будет оптимизирована временная переменная состояния> вдали

Нет state не будет оптимизирован. Тем не менее, До на самом деле самая сложная часть этого вопроса. Пока вы не меняете переменную состояния после (в той же области видимости), вам не о чем беспокоиться.

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

В коде выше state не будет оптимизирован. Это не означает, однако, что StateChanged будет вызываться со значением 2. Это может быть 3, если рабочий поток завершает выполнение перед запуском потока диспетчера.

Суть в том, что захват переменной обеспечивает сохранение значения для использования замыкания, но это не означает, что значение является неизменным.

...