Аннулирование ссылки на объект, пока другой поток выполняет над ней метод (.NET)

StackOverflow https://stackoverflow.com/questions/1290873

Вопрос

(Меня интересует среда .NET CLR)

Что именно происходит, когда один поток изменяет объект, на который ссылается переменная, в то время как другой поток выполняет метод для исходного объекта?

Например, скажем, тип Foo имеет переменную 'Bar' типа Bar, и Bar не имеет состояния на уровне класса (по крайней мере, на данный момент я хотел бы сохранить этот сценарий простым):

// Thread 1
foo.Bar = new Bar();
foo.Bar.SomeMethod();

В то же время, прежде чем это завершит выполнение ...

// Thread 2
foo.Bar = new Bar();

Что происходит с методом, который выполняется (был?) в потоке 1?Все ли, что ему нужно для завершения, уже есть в стеке?

Меняет ли это ситуацию, если поток 2 делает это вместо этого?

foo.Bar = null;
Это было полезно?

Решение

Если вызов гарантированно уже находится внутри SomeMethod(), тогда ничего необычного не произойдет - this является неявным аргументом для методов, поэтому он никогда не будет использовать значение поля (или свойства, каким бы оно ни было) напрямую.

Можете ли вы действительно гарантировать это - другой вопрос.

Другие советы

-- редактировать:исправлено сбивающее с толку предложение.

Ну, на самом деле присвоение переменной будет атомарным, поэтому не похоже, что вызов внезапно осознает "о боже, я равен null!" во время выполнения .someMethod()

Что может однако случается так, что foo.Bar.someMethod() сам по себе вызываться не будет, потому что поток 2 сначала (возможно) установит для него значение null;таким образом, он просто не будет выполняться (он завершится сбоем с исключением null ref).

То же самое относится и к вашему первому примеру;он просто вызовет .Какой-нибудь метод для нового объекта.

Я думаю, вы думаете, что пока все может измениться .Какой-то метод запущен, верно?Нет.Там ничего не изменится.Он по-прежнему будет иметь контекст самого себя.

Что именно происходит, когда один поток изменяет объект, на который ссылается переменная, в то время как другой поток выполняет метод для исходного объекта?

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top